{
"_id" : ObjectId("5a4d0712368ff072a56a66e8"),
"a" : {
"nodes" : [
{
"b" : 1
},
{
"c" : {
"nodes" : [
{
"d" : 2
},
{
"e" : 2
}
]
}
}
]
},
"r" : 1
}
{
"_id" : ObjectId("5a4d0712368ff072a56a66e9"),
"a" : {
"nodes" : [
{
"b" : 4
},
{
"c" : {
"nodes" : [
{
"e" : 9
}
]
}
}
]
},
"r" : 2
}
以上是示例文档,我想找到a.nodes.b * a.nodes.c.nodes.d * a.nodes.c.nodes.e 的总和 我尝试了很多管道,但无法概括聚合。任何帮助,将不胜感激。 节点数组可以在任何级别再次出现。如果我得到了解决方案,我将尝试概括聚合管道。
MongoDB 版本3.2
预期的计算和输出 (1 * 2 * 2)+(4 * 0 * 9)= 4
答案 0 :(得分:0)
我怀疑是否可以处理“节点阵列可以在任何级别再次出现”。聚合。
使用map-reduce可能是这样的:
db.collection.mapReduce(
function(){
let reducer = (result, node) => {
Object.keys(node).map(key => {
if (typeof node[key] === "object") {
if (node[key].nodes && Array.isArray(node[key].nodes)) {
result = node[key].nodes.reduce(reducer, result);
}
} else {
result.product = result.product * node[key];
result.keys.add(key);
}
});
return result;
};
let {product, keys} = this.a.nodes.reduce(reducer, {product: 1, keys: new Set()});
emit(null, {product, keys: Array.from(keys)})
},
function(key, values){
return values.reduce((total, item) => {
let totalSum = total.sum, itemSum = item.product;
for (let key of item.keys) if (!total.keys.includes(key)) totalSum = 0;
for (let key of total.keys) if (!item.keys.includes(key)) itemSum = 0;
return {sum: totalSum + itemSum, keys: Array.from(new Set([...total.keys, ...item.keys]))};
}, {sum: 0, keys: []}).sum;
},
{ query: { "a.nodes": { $exists: true } } , out: { inline: 1 }}
);
Map函数递归地乘以所有键,reducer检查键并计算总数。