代码之家  ›  专栏  ›  技术社区  ›  Adarsh

无重复的MongoDB聚合

  •  1
  • Adarsh  · 技术社区  · 7 年前

    我有以下记录:

    { "_id" : 1, "c" : 120, "b" : [ { "f1" : 10 }, { "f1" : 10 } ] }
    { "_id" :2, "c" : 5, "b" : [ { "f1" : 10 }, { "f1" : 10 } ] }
    

    我需要这样的输出:

    { "_id" : 1, 'total':140}
    { "_id" :2, 'total':25 }
    

    其中,total=同一记录中“c”中的值与f1中的值之和。

    当我解开字段“b”时,它会创建两个具有相同id的文档,因此数据会重复,当我将其相加时,我会得到:

    db.test2.aggregate([ 
      {'$unwind':'$b'},
      {'$project':{'total':{'$add':['$c','$b.f1']}}},
      {'$group':{'_id':'$_id', 'total':{'$sum':'$total'}}}
    ])
    

    输出:

    { "_id" : 1, 'total':260}
    { "_id" :2, 'total':30 }
    

    (这不是我想要的,因为由于放卷过程中的重复,它又在总数中增加了120和5)

    所以我试着:

    db.test2.aggregate([ 
       {'$unwind':'$b'},
       {'$group':{'_id':'$_id', 'c':{'$push': '$c'},'f1':{'$sum':'$b.f1'}}},
       {'$project':{'total':{'$add':[{'$arrayElemAt':['$c',0]},'$f1']}}}
    ])
    

    输出:

    {“\u id”:1,“总计”:140}
    {“\u id”:2,“总计”:25}
    

    (我想要的)

    有没有其他方法可以做到这一点?

    2 回复  |  直到 7 年前
        1
  •  2
  •   s7vr    7 年前

    您可以尝试以下查询。Sum运算符首先计算数组中的Sum,然后进行add运算,以计算其他字段的合计。

    db.test2.aggregate([{
      $project: {
           total: {"$add":["$c", {"$sum":"$b.f1"}]}
        }
    }]
    
        2
  •  1
  •   Alex P.    7 年前

    另一种选择:

    db.test2.aggregate([{
            $project: {
                _id: 0,
                c: "$c",
                b: {
                    $reduce: {
                        input: "$b.f1",
                        initialValue: 0,
                        in: {
                            $add: ["$$value", "$$this"]
                        }
                    }
                }
            }
        },
        {
            $project: {
                _id: 0,
                total: {
                    $sum: ["$c", "$b"]
                }
            }
        }
    ])
    

    这将产生以下结果:

    { 
        "total" : 140
    }
    { 
        "total" : 25
    }
    

    如果你需要场地 _id 然后更换 _id: 0 在两者中 $project _id: 1

    这将产生以下结果:

    { 
        "_id" : 1, 
        "total" : 140
    }
    { 
        "_id" : 2, 
        "total" : 25
    }