2015-10-15 2 views
1

Я пытаюсь написать агрегацию, которая подсчитывает, сколько документов имеет определенные поля (т. Е. Только считать их, если они присутствуют). Объекты выглядят примерно так:Условный счет агрегирования по текущим полям

{ 
     "_id" : ObjectId("5617731fe65e0b19101c7039"), 
     "dateCreated" : ISODate("2015-10-09T07:56:15.068Z"), 
     "dateSent" : ISODate("2015-10-09T07:56:16.682Z"), 
     "dateAttempted" : ISODate("2015-10-09T07:56:16.682Z") 
}, 
{ 
     "_id" : ObjectId("561e37bb537d381bb0ef0ae2"), 
     "dateCreated" : ISODate("2015-10-14T11:08:43.306Z"), 
     "dateSent" : ISODate("2015-10-14T11:09:51.618Z"), 
     "dateAttempted" : ISODate("2015-10-14T11:09:51.618Z"), 
     "dateViewed" : ISODate("2015-10-15T10:09:50.618Z"), 
     "dateOpened" : ISODate("2015-10-15T10:10:01.618Z") 
} 

Я хочу перебрать все документы, считая, где находится поле. Желаемый результат:

{ 
     "total" : 1000, 
     "created" : 1000, 
     "sent" : 990, 
     "attempted" : 995 
     "viewed" : 800, 
     "opened" : 750 
} 

Бонусные баллы, если этот выход можно сгруппировать в день! Я бы предпочел не выполнять новую агрегацию для каждой даты в диапазоне.

Вот что у меня до сих пор, что не работает; она возвращает нули для каждого поля

[ 
    { 
    "$group": { 
     "_id": { 
     "$dayOfMonth": "$dateCreated" 
     }, 
     "total": { 
     "$sum": 1 
     }, 
     "sent": { 
     "$sum": "$dateSent" 
     }, 
     "attempted": { 
     "$sum": "$dateAttempted" 
     }, 
     "viewed": { 
     "$sum": "$dateViewed" 
     }, 
     "clicked": { 
     "$sum": "$dateClicked" 
     } 
    } 
    } 
] 

ответ

4

В $cond и $ifNull операторов помощников здесь:

[ 
    { 
    "$group": { 
     "_id": { 
     "$dayOfMonth": "$dateCreated" 
     }, 
     "total": { 
     "$sum": 1 
     }, 
     "sent": { 
     "$sum": { "$cond": [ { "$ifNull": [ "$dateSent", false ] }, 1, 0 ] } 
     }, 
     "attempted": { 
     "$sum": { "$cond": [ { "$ifNull": [ "$dateAttempted", false ] }, 1, 0 ] } 
     }, 
     "viewed": { 
     "$sum": { "$cond": [ { "$ifNull": [ "$dateViewed", false ] }, 1, 0 ] } 
     }, 
     "clicked": { 
     "$sum": { "$cond": [ { "$ifNull": [ "$dateClicked", false ] }, 1, 0 ] } 
     } 
    } 
    } 
] 

$ifNull будет возвращать либо поле, где присутствует (логический true) или альтернативное значение false , И $cond смотрит на это условие и возвращает либо 1, где true, либо 0, где false, чтобы указать условный счет.

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