我有一个对象集合:
{
"_id" : "01",
"properties" : {
"colors" : {
"red" : 0.8891772,
"blue" : 0.7580757,
"green" : 0.4345628,
"white" : 0.7373822,
"black" : 0.93228924,
...
"purple" : 0.83328924,
}
}
颜色有更多上面显示的键。此外,并非每个对象都具有完全相同的键,例如对象可能根本没有 properties.colors.red。
我需要对颜色键的值求和,以便输出看起来像:
/* 1 */
{
"key" : "Red",
"value" : 2723.1982
}
/* 2 */
{
"key" : "Blue",
"value" : 972172.271
}
...
其中值是该颜色值的总和。
编辑
事实上,比每个属性的总和更好。颜色是原始集合中文档总数的总和的平均值。
例如:
{
"_id" : "01",
"properties" : {
"colors" : {
"red" : 2.0,
"blue" : 4.0,
}
}
{
"_id" : "02",
"properties" : {
"colors" : {
"red" : 2.0,
"black" : 8.0,
}
}
应该导致:
/* 1 */
{
"key" : "red",
"value" : 2.0
}
/* 2 */
{
"key" : "blue",
"value" : 2.0
}
/* 3 */
{
"key" : "black",
"value" : 4.0
}
最佳答案
您必须同时运行两个管道:一个只对所有文档进行计数,另一个按颜色聚合。您可以使用 $facet 来做到这一点.第一个管道相当简单:你只需要 $count获取元素的数量。您可以使用 $objectToArray 开始第二次聚合这会将您的嵌套对象转换为一组键和值(k
和 v
字段)。然后你可以运行 $unwind在该数组上获取每个条目的单个文档以便能够使用 $group和 $sum
。然后你只需要 $project
来 reshape 最终结果。最后你需要 $divide将每个结果除以集合中的元素数。尝试:
db.col.aggregate([
{
$facet: {
total: [ { $count: "value" } ],
agg: [
{
$project: {
colors: {
$objectToArray: "$properties.colors"
}
}
},
{
$unwind: "$colors"
},
{
$group: {
_id: "$colors.k",
v: { $sum: "$colors.v" }
}
}
]
}
},
{
$unwind: "$total"
},
{
$unwind: "$agg"
},
{
$project: {
_id: 0,
key: "$agg._id",
value: { $divide: [ "$agg.v", "$total.value" ] }
}
}
])
关于database - MongoDB:在没有 MapReduce 的情况下对对象中的值求和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53461476/