【发布时间】:2014-10-21 15:13:59
【问题描述】:
我有一种情况,我需要根据一个汇总字段值出现次数的数组值执行分组操作。然后过滤计数并准备结果,以便可以根据条件显示它们。从本质上讲,如果您仅使用 find 功能,文档就会转换回它们的呈现方式。由于matchedDocuments数组中收集的项目数量,我遇到了临时文档太大的问题。任何有关如何改进这一点的建议都会有所帮助。
db.collection1.aggregate([
{
'$unwind': '$arrayOfValues'
}, {
'$group': {
'_id': '$arrayOfValues',
'x_count': {
$sum: {
$cond: [{
$eq: ['$field.value', 'x']
},
1, 0
]
}
},
'y_count': {
$sum: {
$cond: [{
$eq: ['$field.value', 'y']
},
1, 0
]
}
},
'matchedDocuments': {
'$push': '$$CURRENT'
}
}
},
{'$match': {'$or': [{'x_count': {'$gte': 2}}, {'y_count': { '$gte': 1}}]}},
{'$unwind': '$matchedDocuments'},
{
'$group': {
'_id': '$matchedDocuments.key',
'document': {
'$last': '$$CURRENT.matchedDocuments'
}
}
}
], {
allowDiskUse: true
})
以下是一些示例文档和基于上述标准的预期结果:
// Sample documents
{ "_id" : ObjectId("5407c76b7b1c276c74f90524"), "field" : "x", "arrayOfValues" : [ "a", "b", "c" ] }
{ "_id" : ObjectId("5407c76b7b1c276c74f90525"), "field" : "x", "arrayOfValues" : [ "b", "c" ] }
{ "_id" : ObjectId("5407c76b7b1c276c74f90526"), "field" : "z", "arrayOfValues" : [ "a" ] }
{ "_id" : ObjectId("5407c76b7b1c276c74f90527"), "field" : "x", "arrayOfValues" : [ "a", "c" ] }
{ "_id" : ObjectId("5407c76b7b1c276c74f90528"), "field" : "z", "arrayOfValues" : [ "b" ] }
{ "_id" : ObjectId("5407c76b7b1c276c74f90529"), "field" : "y", "arrayOfValues" : [ "k" ] }
// Expected Result
[
{ "_id" : ObjectId("5407c76b7b1c276c74f90524"), "field" : "x", "arrayOfValues" : [ "a", "b", "c" ] }
{ "_id" : ObjectId("5407c76b7b1c276c74f90525"), "field" : "x", "arrayOfValues" : [ "b", "c" ] }
{ "_id" : ObjectId("5407c76b7b1c276c74f90527"), "field" : "x", "arrayOfValues" : [ "a", "c" ] }
{ "_id" : ObjectId("5407c76b7b1c276c74f90529"), "field" : "y", "arrayOfValues" : [ "k" ] }
]
【问题讨论】:
-
问题出在你的第一个分组键上。但是,由于您对刚刚展开的数组中的值进行了分组,因此很难看到您在此处实际尝试执行的操作。文档样本和预期结果通常最能说明您的意图。
-
我添加了示例文档和预期结果以帮助可视化问题。
-
为什么不统计
arrayOfValues数组大小的文档呢?这将使聚合成为field的每个值的简单查找。 -
我认为这不会帮助解决这个问题。您可以将 arrayOfValues 视为每个文档的分组。我希望按每个组中出现值 x (>= 2) 或 y (>= 1) 的字段的出现次数过滤结果。
标签: mongodb mongodb-query aggregation-framework