2016-05-31 4 views
3

Я запускаю некоторые агрегирующие запросы в MongoDB 3.2. Я хотел бы сгруппировать документы по полю со средним значением в другом числовом поле. Мне нужно среднее значение, чтобы игнорировать значения 0. Проблема в том, что я не могу полностью фильтровать документ, потому что для подсчета требуется другое поле.

Проиллюстрируем:

Это структура моих документов:

{"stringToGroupByOn":"foo", "valueToAvg":42, "valueToSum":21} 
{"stringToGroupByOn":"foo", "valueToAvg":0, "valueToSum":13} 

Я не могу просто фильтровать, как это:

db.foobar.aggregate([ 
    { 
     $match : { valueToAvg : { $gt : 0 } } 
    }, 
    { 
     $group : { 
      _id : '$stringToGroupByOn', 
      avg : { $avg : '$valueToAvg' }, 
      count : { $sum : '$valueToSum' } 
     } 
    } 
]) 

Потому что я теряю значение 13 для сосчитать.

Как вы думаете, есть ли способ сделать это только в одном запросе?

+0

, что Монго версию мы имеем? – profesor79

+0

Извините, что забыл упомянуть об этом: версия 3.2 – eli0tt

ответ

2

Вы можете использовать $ cond в проекции, чтобы установить значение null вместо 0, поскольку значение null не учитывается при использовании среднего значения.

db.avg.aggregate([ 
    {$project:{ 
     _id:1, 
     valueToSum:1, 
     stringToGroupByOn:1, 
     valueToAvg:{$cond: 
      { if: { $eq: [ "$valueToAvg", 0 ] }, 
        then: null, 
        else: "$valueToAvg" }}   
     }}, 
    { 
     $group : { 
      _id : '$stringToGroupByOn', 
      avg : { $avg : '$valueToAvg' }, 
      count : { $sum : '$valueToSum' } 
     } 
    } 

выход:

{ 
    "_id" : "foo", 
    "avg" : 42.0, 
    "count" : 34.0 
} 
Смежные вопросы