鉴于这些文件:
{
values: [
{ attribute: 1 },
{ attribute: 2 },
{ attribute: 3 },
{ attribute: 4 },
]
},
{
values: [
{ attribute: 2 },
{ attribute: 3 },
{ attribute: 4 },
]
},
{
values: [
{ attribute: 2 },
{ attribute: 3 },
]
}
我正在尝试获取常见的“属性”值:
[ 2, 3 ]
我正在研究聚合器框架,但我发现没有什么可以真正满足我现在的需求。
我正在使用Mongo 2.4.6。
提前感谢您的回答!
修改
事实上,我的文档可以有重复的属性(但我想每个文档只计算一次)。
鉴于此数据
{
values: [
{ attribute: 1 },
{ attribute: 2 },
{ attribute: 3 },
{ attribute: 3 },
{ attribute: 4 },
]
},
{
values: [
{ attribute: 2 },
{ attribute: 2 },
{ attribute: 3 },
{ attribute: 4 },
]
},
{
values: [
{ attribute: 2 },
{ attribute: 3 },
]
}
然后查询应返回:
{
"result" : [
{
"values" : 2
},
{
"values" : 3
}
],
"ok" : 1
}
Anand,您发布的查询将计算属性“2”4次,而不是3次。 我试图修改它,但这对我来说仍然很神秘......
提前致谢。
答案 0 :(得分:1)
我不确定我是否完全理解你的问题,但我会对它进行一次拍摄。
如果您只想查找集合中每个文档中存在的属性,一种方法是在单独的查询中获取文档计数,然后使用如下所示的聚合查询。 / p>
db.collection.aggregate([
// Unwind the values array
{ "$unwind" : "$values"},
// Group by "values.attribute" and get the count for each
{ "$group" : {_id:"$values.attribute", count:{$sum:1}}},
// Filter only those documents where count equals number of docs in the collection (i.e., 3)
{ "$match" : {count:3}}, // Replace 3 with document count
// Project phase to make the result prettier and in the format you want
{ "$project" :{_id:0, values:"$_id"}}
])
这是您运行上述查询时获得的输出:
{
"result" : [
{
"values" : 3
},
{
"values" : 2
}
],
"ok" : 1
}
我不认为这可以在单个查询中实现(即,没有为文档计数运行单独的查询)。如果有更好的方法,可能有人会在这里发帖。
编辑:对于您所描述的边缘情况,您可以利用每个文档中存在的_id
字段,并通过添加额外的$ group阶段在整个集合中是唯一的包括_id
:
db.collection.aggregate([
// Unwind the values array
{ "$unwind" : "$values"},
// Group by "_id" and "values.attribute" to pick just one element from the array per document
{ "$group" : {_id:{_id:"$_id", attrValue: "$values.attribute"}}},
// Group by "values.attribute" and get the count for each
{ "$group" : {_id:"$_id.attrValue", count:{$sum:1}}},
// Filter only those documents where count equals number of docs in the collection (i.e., 3)
{ "$match" : {count:3}}, // Replace 3 with document count
// Project phase to make the result prettier and in the format you want
{ "$project" :{_id:0, values:"$_id"}}
])
答案 1 :(得分:0)
我们已经提出了这个解决方案:
db.collection.aggregate(
{ $project: { "values.attribute": 1} },
{ $unwind: "$values" },
{ $group: {
_id : "$_id",
attribute: {$addToSet:"$values.attribute"}
}
},
{ $unwind: "$attribute" },
{ $group: { _id: "$attribute", count: { $sum: 1 } } },
{ "$match" : {count:3}},
)
并且addToSet似乎比复合键上的组更快。
非常感谢Anand,非常感谢您的帮助!