$avg ในการรวม mongodb

เอกสารมีลักษณะดังนี้:

   {
    "_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" } คะแนนคือ 30 สำหรับเอกสาร { "NAME" : "asd" } และ { evaluator_id : "e2" } คะแนนคือ 0< /strong> สำหรับ { "NAME" : "asd" } ในกรณีนี้ ฉันต้องการให้ AVG_SCORE เป็น 30 เท่านั้น (ไม่ใช่ (30 + 0) / 2 = 15)

เป็นไปได้ไหมโดยการรวมกลุ่ม??

ใครก็ได้ช่วยฉันหน่อย


person manojpt    schedule 12.03.2015    source แหล่งที่มา


คำตอบ (1)


เป็นไปได้โดยการวาง $match ระหว่าง ไปป์ไลน์การรวม $unwind และ $group เพื่อกรองอาร์เรย์ที่ตรงกับเงื่อนไขที่ระบุก่อนเพื่อรวมไว้ในการคำนวณโดยเฉลี่ย และนั่นคือ อาร์เรย์คะแนนโดยที่คะแนนที่ได้รับไม่เท่ากับ 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
}
person chridam    schedule 12.03.2015
comment
อีกกรณีหนึ่ง: หาก ทั้ง e1 และ e2 ให้คะแนน 0 NAME : asd จะพลาดในเอาต์พุต แต่สิ่งที่ฉันต้องการคือ (0 + 0) / 2 = 0 หมายถึง ถ้าคะแนนทั้งสองเป็น 0 ค่าเฉลี่ยควรเป็น 0 และ ถ้าคะแนนใดคะแนนหนึ่งเป็น › 0, เฉลี่ย = (คะแนนซึ่งก็คือ › 0) - person manojpt; 13.03.2015