mongodb 聚合中的 $avg

$avg in mongodb aggregation

文档看起来像这样:

   {
    "_id" : ObjectId("361de42f1938e89b179dda42"),
    "user_id" : "u1",
    "evaluator_id" : "e1",
    "candidate_id" : ObjectId("54f65356294160421ead3ca1"),
    "OVERALL_SCORE" : 150,
    "SCORES" : [ 
      { "NAME" : "asd", "OBTAINED_SCORE" : 30}, { "NAME" : "acd", "OBTAINED_SCORE" : 36}
      ]
   }

聚合函数:

 db.coll.aggregate([ {$unwind:"$SCORES"}, {$group : { _id : { user_id : "$user_id", evaluator_id : "$evaluator_id"}, AVG_SCORE : { $avg : "$SCORES.OBTAINED_SCORE" }}} ])

假设有两个文档相同"user_id"(比如u1)和不同"evaluator_id"(说 e1 和 e2)。

例如:

1) 平均值将像这样计算 ((30 + 20) / 2 = 25)。这对我有用。

2) 但对于 { evaluator_id : "e1" } 文档,score 是 30 for { "NAME" : "asd" } 和 { evaluator_id : "e2" } 文档,{ "NAME" : "asd" } 的 分数为 0。在这种情况下,我希望 AVG_SCORE 仅为 30(不是 (30 + 0) / 2 = 15).

是否可以通过聚合实现?

谁能帮帮我

可以通过在$unwind$group聚合管道之间放置一个$match来首先过滤符合指定条件的数组包括在平均计算中,即获得的分数不等于 0 的分数数组 "SCORES.OBTAINED_SCORE" : { $ne : 0 }

db.coll.aggregate([ 
    {
        $unwind: "$SCORES"
    },     
    { 
        $match : { 
            "SCORES.OBTAINED_SCORE" : { $ne : 0 } 
        } 
    },
    {
        $group : { 
            _id : { 
                user_id : "$user_id", 
                evaluator_id : "$evaluator_id"
            }, 
            AVG_SCORE : { 
                $avg : "$SCORES.OBTAINED_SCORE" 
            }
        }
     } 
 ])

例如这个文档的聚合结果:

{
    "_id" : ObjectId("5500aaeaa7ef65c7460fa3d9"),
    "user_id" : "u1",
    "evaluator_id" : "e1",
    "candidate_id" : ObjectId("54f65356294160421ead3ca1"),
    "OVERALL_SCORE" : 150,
    "SCORES" : [ 
        {
            "NAME" : "asd",
            "OBTAINED_SCORE" : 0
        }, 
        {
            "NAME" : "acd",
            "OBTAINED_SCORE" : 36
        }
    ]
}

将产生:

{
    "result" : [ 
        {
            "_id" : {
                "user_id" : "u1",
                "evaluator_id" : "e1"
            },
            "AVG_SCORE" : 36
        }
    ],
    "ok" : 1
}