$avg dalam agregasi mongodb

Dokumen terlihat seperti ini:

   {
    "_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}
      ]
   }

Fungsi agregasi:

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

Misalkan ada dua dokumen dengan "user_id" yang sama (misalnya u1) dan "evaluator_id" yang berbeda (misalnya e1 dan e2).

Misalnya:

1) Rata-rata akan bekerja seperti ini ((30 + 20) / 2 = 25). Ini berhasil untuk saya.

2) Namun untuk dokumen { evaluator_id : "e1" }, skornya adalah 30 untuk dokumen { "NAME" : "asd" } dan { evaluator_id : "e2" }, skornya adalah 0< /strong> untuk { "NAMA" : "asd" }. Dalam hal ini, saya ingin AVG_SCORE menjadi 30 saja (bukan (30 + 0) / 2 = 15).

Apakah mungkin melalui agregasi??

Adakah yang dapat membantu saya.


person manojpt    schedule 12.03.2015    source sumber


Jawaban (1)


Hal ini dimungkinkan dengan menempatkan $match di antara pipeline agregasi $unwind dan $group untuk terlebih dahulu memfilter array yang cocok dengan kondisi yang ditentukan untuk dimasukkan dalam perhitungan rata-rata dan yaitu, array skor yang skor yang diperoleh tidak sama dengan 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" 
            }
        }
     } 
 ])

Misalnya, hasil agregasi untuk dokumen ini:

{
    "_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
        }
    ]
}

akan menghasilkan:

{
    "result" : [ 
        {
            "_id" : {
                "user_id" : "u1",
                "evaluator_id" : "e1"
            },
            "AVG_SCORE" : 36
        }
    ],
    "ok" : 1
}
person chridam    schedule 12.03.2015
comment
Satu kasus lagi: Jika e1 dan e2 memberikan skor 0, NAME : asd akan terlewatkan dalam output. Tapi yang saya butuhkan adalah (0 + 0) / 2 = 0. Artinya jika kedua skornya 0, rata-ratanya harus 0 dan jika salah satu skornya adalah › 0, rata-rata = (skor yang › 0). - person manojpt; 13.03.2015