假设我有以下收集结构:
{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 )。我至少需要三维文档,我已经认为通过,其他一切都意味着阅读时性能会大幅下降。
或者有可能在MongoDB中这样做我错过了吗?
我正在使用golang,因此应该有一个维护良好的数据库系统包。
答案 0 :(得分:4)
要执行此操作,您需要使用$sort
运算符按{1}}按升序对文档进行排序,然后value
$group
对其进行排序并使用$push
}运算符返回“值”数组。从那里开始,由于聚合结果是一个数组,你可以使用.map()
方法返回“{/ 1}}为_id
的”键/值“数组,值中前两个元素的key
数组(按.splice()
或.slice()
返回)
type
输出
values
从MongoDB 3.2开始,您可以在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) }})
阶段使用$slice
运算符。
[
{
"type" : 1,
"values" : [ "d", "e" ]
},
{
"type" : 2,
"values" : [ "a", "b" ]
}
]
答案 1 :(得分:1)
图形数据库可能是MongoDB的一个很好的替代品,因为它们更适合于关系建模。您不必在每个文档中重复一个类型,您可以从中创建一个节点。
根据您对数据建模的方式,您询问的任务可能更简单或更困难。不确定是否有可能内置开箱即用的解决方案,但在最坏的情况下,您可能只是将您的值链接为由关系连接的节点,为每种类型维护某种排序的值列表,这将使为每种类型轻松获取N-top值(并且您不必检索不必要的数据)。
Neo4j有library支持Go,但不确定它是否成熟......
对于MongoDB,您也可以尝试使用自己的aggregation capabilities。我对它并不是很熟悉,但似乎有点难,因为$ group聚合的可能累加器数量有限(你可能需要将限制应用于$ push,但似乎不太可能)...