2015-03-12 3 views
0

документа выглядит следующим образом: функция

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

Aggregation:

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

Предположим, что при наличии двух документов с же "user_id" (скажем u1) и различного «valuator_id» (скажем, e1 и e2).

Например:

1) Среднее будет работать, как это ((30 + 20)/2 = 25). Это работает для меня.

2) Но для {evaluator_id: "e1"} документа Счет 30 для { "NAME": "ASD"} и {evaluator_id: "e2"} документа Счет 0 для { " NAME ":" asd "}. В этом случае я хочу, чтобы AVG_SCORE был 30 только (не (30 + 0)/2 = 15).

Возможно ли это посредством агрегации ??

Может ли кто-нибудь помочь мне.

ответ

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 
} 
+0

Еще один случай: если ** оба e1 и e2 дали оценку 0 **, NAME: «asd» будет пропущен на выходе. Но мне нужно ** (0 + 0)/2 = 0. ** Обозначает **, если оба показателя равны 0, avg должно быть 0 ** и **, если один из баллов равен> 0, avg = (оценка> 0). ** – manojpt

Смежные вопросы