【问题标题】:Get the 2 alphabetically first documents by type按类型获取 2 个按字母顺序排列的第一个文档
【发布时间】:2015-08-11 11:44:10
【问题描述】:

假设我有以下集合结构:

{type: 1, value: "f"},
{type: 2, value: "c"},
{type: 2, value: "b"},
{type: 1, value: "d"},
{type: 1, value: "e"},
{type: 2, value: "a"}

现在我想为每个“类型”获取 2 个按字母顺序排列的第一个文档(“值”),结果应该如下所示:

{type: 1, value: "d"},
{type: 1, value: "e"},
{type: 2, value: "a"},
{type: 2, value: "b"},

使用 MongoDB,我必须检索所有文档并删除不必要的文档。

是否有另一个 NoSQL 系统具有内置函数来执行此操作?

另一个简洁的要求是可以简单地更新超过 2 维的嵌套文档,这在 MongoDB 中也是不可能的,因为您只能使用一次位置运算符“$”(请参阅​​https://jira.mongodb.org/browse/SERVER-831)。我至少需要 3 维文档,我已经考虑过了,其他一切都意味着阅读时性能会大幅下降。

或者是否有可能在我缺少的 MongoDB 中做到这一点?

我正在使用 golang,所以数据库系统应该有一个维护良好的包。

【问题讨论】:

    标签: javascript mongodb mongodb-query aggregation-framework


    【解决方案1】:

    为此,您需要使用$sort 运算符按value 升序对文档进行排序,然后按_id$group 进行排序,并使用$push 运算符返回“值”数组。从那里开始,由于 aggregation 结果是一个数组,您可以使用.map() 方法返回“键/值”数组,其中keytypevalues 第一个数组值中的两个元素(由.splice().slice() 返回)

    db.collection.aggregate([
        { "$sort": { "value": 1 }}, 
        { "$group": { "_id": "$type", "values": { "$push": "$value" }}}
    ]).map( function( doc ) { 
              return { "type": doc._id, "values": doc.values.splice(0, 2) }})
    

    输出

     [
         {
             "type" : 1,
             "values" : [ "d", "e" ]
         },
         {
             "type" : 2,
             "values" : [ "a", "b" ]
         }
    ]
    

    从 MongoDB 3.2 开始,您可以在 $project 阶段使用 $slice 运算符。

    db.collection.aggregate([
        { "$sort": { "value": 1 }}, 
        { "$group": { "_id": "$type", "values": { "$push": "$value" }}},
        { "$project": { "values": { "$slice": [ "$values", 0, 2 ] }}}
    ])
    

    【讨论】:

    • 非常感谢!它对我的问题帮助很大。
    【解决方案2】:

    图形数据库可能是 MongoDB 的一个不错的替代品,因为它们更适合关系建模。您不必在每个文档中重复一个类型,您可以从中创建一个节点。

    根据您对数据建模的方式,您询问的任务可能更简单或更困难。不确定是否有内置的开箱即用解决方案的机会,但在最坏的情况下,您可以简单地将值链接为由关系连接的节点,为每种类型维护某种排序的值列表,这将使轻松获取每种类型的 N-top 值(并且您不必检索不必要的数据)。

    有一个library for Neo4j 支持 Go,但不确定它是否成熟...

    说到 MongoDB,你也可以尝试使用它自己的aggregation capabilities。我对它不是很熟悉,但它似乎有点难,因为 $group 聚合具有有限数量的可能累加器(您可能需要对 $push 应用限制,但这似乎是不可能的)...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-25
      • 2011-04-26
      • 2021-09-29
      • 1970-01-01
      相关资源
      最近更新 更多