Mongodb 聚合中对数组元素求和

2024-05-17

我有以下收藏c每个文档内的数组

{
  {
    id: 1,
    k: 2.2,
    type: "dog",
    c: [ {parentId:1, p:2.2}, {parentId:1, p:1.4} ]
  },

  {
    id: 2,
    k: 4.3,
    type:"cat",
    c: [ {parentId:2, p:5.2}, {parentId:2, p:4.5} ]
  }
}

parentId在每个子文档内c是包含文档的 id。

我想按以下方式对所有文档进行分组type并且在每组中知道总和k以及所有的总和p在该组的所有数组中。

目前我正在总结k在小组赛阶段但总结p在应用程序的结果数组中。我想做总结p in DB!

这就是我目前所做的:

db.myCol.aggregate([

{ 
  $group: {
    _id: { type: '$type'},
    k: {$sum: '$k'}, // sum k values, very easy!
    // p: {$sum: '$c.0.p'} <==== Does not work, too
    c: {$addToSet: '$c'} // add to each group all c arrays of group's members
  }   
}
], function(err, res) {
   // go over c-arrays and sum p values
   var accP = 0; // accumulator for p values
   for ( var i=0; i<res.length; i++ ) {
     var c = res[i].c;
     for (var j=0;j<c.length; j++) {
       var c2 = c[j];
       for ( var k=0; k<c2.length; k++) { // finally got to objects c array
          accP += c2[k].p;
       }
     }
     res[i].c = accP; // replace array with accumulated p value
   }
});

你需要先$group https://docs.mongodb.org/manual/reference/operator/aggregation/group/#pipe._S_group按“类型”分类的文档,请使用$sum https://docs.mongodb.org/manual/reference/operator/aggregation/sum/#grp._S_sum累加器运算符返回“k”的总和并使用$push https://docs.mongodb.org/manual/reference/operator/aggregation/push/#grp._S_push它返回“c”的二维数组。现在你需要两个“$放松” https://docs.mongodb.org/manual/reference/operator/aggregation/unwind/#pipe._S_unwind对“c”二维数组进行非规范化的阶段。管道中的最后一个阶段是另一个阶段$group https://docs.mongodb.org/manual/reference/operator/aggregation/group/#pipe._S_group使用“点表示法”计算“p”总和的阶段

db.collection.aggregate([
    { '$group': {
        '_id': '$type', 
        'k': { '$sum': '$k' }, 'c': { '$push': '$c' } 
    } }, 
    { '$unwind': '$c' }, 
    { '$unwind': '$c' },
    { '$group': { 
        '_id': '$_id', 
        'k': { '$first': '$k' }, 
        'c': { '$sum': '$c.p' }
    }}
])

其产量:

{ "_id" : "dog", "k" : 2.2, "c" : 3.6 }
{ "_id" : "cat", "k" : 4.3, "c" : 9.7 }

从 3.2 版本开始 https://docs.mongodb.org/manual/release-notes/3.2/#accumulator-expression-availability,以下累加器表达式,以前仅在$group阶段,现在也可以在$project stage.

这意味着我们可以利用这一点并使用$sum累加器运算符$project https://docs.mongodb.org/manual/reference/operator/aggregation/project/#pipe._S_project。当然$map运算符为每个文档返回一个“p”数组。

db.collection.aggregate([
    { '$project': { 
        'type': 1, 
        'k': 1, 
        'c': { 
            '$sum': {
                '$map': { 
                    'input': '$c', 
                    'as': 'subc', 
                    'in': '$$subc.p'
                }
            }
        }
    }}, 
    { '$group': { 
        '_id': '$type', 
        'k': { '$sum': '$k' }, 
        'c': { '$sum': '$c' }
    }}
])

返回:

{ "_id" : "cat", "k" : 4.3, "c" : 9.7 }
{ "_id" : "dog", "k" : 2.2, "c" : 3.6 }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Mongodb 聚合中对数组元素求和 的相关文章

随机推荐