Mongodb: 聚合:对 $group 之前的数组中的值求和
Mongodb: Aggregation : sum up values in an array before $group
我有一组具有以下结构的文档:
{
_id: 1,
array: [
{value: 10 },
{value: 11 },
{value: 12 }
]
}
我想对集合进行聚合查询:
得到每个项目的比例。 (例如,项目 1 的比例将是项目 1 的 value
除以所有三个项目的值之和。
注意:我想在单个查询中执行此操作。
这里的基本思想是$unwind
the array, $group
the document and then apply to each array member. This works better for MongoDB 2.6 or greater due to the $map
运算符:
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" ]
}
}
}
}}
])
在任何一种情况下,如果您实际上 "aggregating" 文档之外的任何内容,在客户端代码中执行此计算的效率要高得多。 $unwind
由于其作用,此处的 $unwind
可能会变得非常昂贵。
此外,如果您只是将 "total" 存储为另一个元素,那么简单的 $project
就是您所需要的,而且成本非常低通过它自己。保持总计更新只是对数组 $inc
operator as you $push
新元素的简单使用。
这是您需要的聚合管道:
[
{$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']
}
}
}
]
我有一组具有以下结构的文档:
{
_id: 1,
array: [
{value: 10 },
{value: 11 },
{value: 12 }
]
}
我想对集合进行聚合查询:
得到每个项目的比例。 (例如,项目 1 的比例将是项目 1 的 value
除以所有三个项目的值之和。
注意:我想在单个查询中执行此操作。
这里的基本思想是$unwind
the array, $group
the document and then apply to each array member. This works better for MongoDB 2.6 or greater due to the $map
运算符:
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" ]
}
}
}
}}
])
在任何一种情况下,如果您实际上 "aggregating" 文档之外的任何内容,在客户端代码中执行此计算的效率要高得多。 $unwind
由于其作用,此处的 $unwind
可能会变得非常昂贵。
此外,如果您只是将 "total" 存储为另一个元素,那么简单的 $project
就是您所需要的,而且成本非常低通过它自己。保持总计更新只是对数组 $inc
operator as you $push
新元素的简单使用。
这是您需要的聚合管道:
[
{$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']
}
}
}
]