阅读the docs,我看到你可以获得文档数组中的元素数量。例如,给出以下文件:
{ "_id" : 1, "item" : "ABC1", "description" : "product 1", colors: [ "blue", "black", "red" ] }
{ "_id" : 2, "item" : "ABC2", "description" : "product 2", colors: [ "purple" ] }
{ "_id" : 3, "item" : "XYZ1", "description" : "product 3", colors: [ ] }
以及以下查询:
db.inventory.aggregate([{$project: {item: 1, numberOfColors: { $size: "$colors" }}}])
我们将获得每个文档的colors
数组中的元素数量:
{ "_id" : 1, "item" : "ABC1", "numberOfColors" : 3 }
{ "_id" : 2, "item" : "ABC2", "numberOfColors" : 1 }
{ "_id" : 3, "item" : "XYZ1", "numberOfColors" : 0 }
我无法弄清楚是否以及如何直接从查询中总结所有文档中的所有颜色,即:
{ "totalColors": 4 }
答案 0 :(得分:2)
您可以使用以下查询来获取所有文档中所有颜色的计数:
db.inventory.aggregate([
{ $unwind: '$colors' } , // expands nested array so we have one doc per each array value
{ $group: {_id: null, allColors: {$addToSet: "$colors"} } } , // find all colors
{ $project: { totalColors: {$size: "$allColors"}}} // find count of all colors
])
答案 1 :(得分:1)
无限好的是$sum
:
$size
db.inventory.aggregate([
{ "$group": { "_id": null, "totalColors": { "$sum": { "$size": "$colors" } } }
])
如果你想要"在每个文件中都是不同的"然后你会改为:
db.inventory.aggregate([
{ "$group": {
"_id": null,
"totalColors": {
"$sum": {
"$size": { "$setUnion": [ [], "$colors" ] }
}
}
}}
])
其中$setUnion
取值为["purple","blue","purple"]
的值,并将其作为"设置为#{1}}。使用"不同的项目"。
如果你真的想要"不同的文件"然后不积累" distinct"到一个文件。这会导致性能问题,并且无法扩展到大型数据集,并且可能会破坏16MB BSON限制。而是通过密钥自然积累:
["purple","blue"]
你只使用$unwind
,因为你想要" distinct"数组中的值与其他文档组合在一起。通常应该避免使用$unwind
,除非在"分组键"中访问数组中包含的值。 $group
的db.inventory.aggregate([
{ "$unwind": "$colors" },
{ "$group": { "_id": "$colors" } },
{ "$group": { "_id": null, "totalColors": { "$sum": 1 } } }
])
。如果不是,最好使用其他运算符处理数组,因为_id
会创建一个"副本"每个数组元素的整个文档。
当然,在这里简单地使用.distinct()
也没有错,这将返回" distinct"值"作为数组",您只需在代码中测试Array.length()
:
$unwind
对于简单的操作,您要问的是,对于简单的"不同元素的数量而言,整体最快方法"。当然,限制仍然是结果不能超过作为有效载荷的16MB BSON限制。这是您推荐var totalSize = db.inventory.distinct("colors").length;
的地方。