按类型获取 2 个按字母顺序排列的第一个文档

Get the 2 alphabetically first documents by type

假设我有以下集合结构:

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

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

{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,所以应该有一个维护良好的数据库系统包。

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

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

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

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

为此,您需要使用 $sort operator and then $group them by _id and use the $push operator to return array of "values". From there and since aggregation result is an array you can you can use the .map() method which returns array of "key/values" where key is type and values array of first two elements in values ( return by .splice() or .slice() )

value 升序对文档进行排序
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 ] }}}
])