按类型获取 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 ] }}}
])
假设我有以下集合结构:
{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 ] }}}
])