我有一系列具有以下结构的文件:
{
_id: 1,
array: [
{value: 10 },
{value: 11 },
{value: 12 }
]
}
我想对集合进行汇总查询:
得到每个项目的比例。 (即例如项目1的比例为项目1的value
除以所有三项的值的总和。
注意: 我想在一次查询中执行此操作。
答案 0 :(得分:5)
这里的基本思想是$unwind
数组,$group
文档,然后应用于每个数组成员。由于$map
运算符,这对MongoDB 2.6或更高版本更有效:
db.collection.aggregate([
{ "$unwind": "$array" },
{ "$group": {
"_id": "$_id",
"array": { "$push": "$array" },
"total": { "$sum": "$array.value" }
}},
{ "$project": {
"array": {
"$map": {
"input": "$array",
"as": "el",
"in": {
"value": "$$el.value",
"prop": {
"$divide": [ "$$el.value", "$total" ]
}
}
}
}
}}
])
或者使用早期版本:
db.collection.aggregate([
{ "$unwind": "$array" },
{ "$group": {
"_id": "$_id",
"array": { "$push": "$array" },
"total": { "$sum": "$array.value" }
}},
{ "$unwind": "$array" },
{ "$group": {
"_id": "$_id",
"array": {
"$push": {
"value": "$array.value",
"prop": {
"$divide": [ "$array.value", "$total" ]
}
}
}
}}
])
在任何一种情况下,如果你实际上并没有"汇总"除了文档之外的任何东西,在客户端代码中进行此计算要高效得多。由于它的作用,$unwind
在这里会变得非常昂贵。
此外,如果您只是存储"总计"作为另一个元素,那么简单的 $project
就是您所需要的,而且本身成本非常低。保持更新总数只是简单地使用$inc
运算符作为$push
数组的新元素。
答案 1 :(得分:1)
以下是您需要的聚合管道:
[
{$unwind: '$array'},
{
$group: {
_id: '$_id',
array: {$push: '$array'},
sum: {$sum: '$array.value'}
}
},
{$unwind: '$array'},
{
$project: {
_id: 1,
'array.value': 1,
'array.proportion': {
$divide: ['$array.value', '$sum']
}
}
}
]