2015-04-21 4 views
4

я следующий конвейер в моей агрегации:Mongoose совокупный выходной формат

$group: { 
    _id: { 
     $dateToString: { 
      format: '%Y-%m-%d', 
      date: '$created_at' 
     } 
    }, 
    num: { 
     $sum: 1 
    } 
} 

Это возвращает мне сумму документов, сгруппированных по данным, например:

[ 
    { 
     "_id": "2015-04-21", 
     "num": 1871 
    } 
] 

Теперь я хотел бы изменить вывод на что-то вроде этого:

[ 
    ["2015-04-21", 1871] 
] 

Возможно ли это в рамках агрегационного трубопровода? Или мне нужно написать собственный метод преобразования?

ответ

3

Вы можете использовать $addToSet и $setUnion операторов в вашем трубопроводе следующим образом:

db.collection.aggregate([ 
    { 
     "$group": { 
      "_id": { 
       "$dateToString": { 
        "format": "%Y-%m-%d", 
        "date": "$created_at" 
       } 
      }, 
      "num": { 
       "$sum": 1 
      } 
     } 
    }, 
    { 
     "$group": { 
      "_id": "$_id", 
      "A": { 
       "$addToSet": "$_id" 
      }, 
      "B": { 
       "$addToSet": "$num" 
      } 
     } 
    }, 
    { 
     "$project": { 
      "_id": 0, 
      "finalArray": { 
       "$setUnion": [ "$A", "$B" ] 
      } 
     } 
    } 
]); 

Выход:

/* 0 */ 
{ 
    "result" : [ 
     { 
      "finalArray" : ["2015-04-21", 1871] 
     } 
    ], 
    "ok" : 1 
} 
+1

Это именно то, что я хотел, очень впечатлен тем, как много Монго может сделать , –

+1

@woutr_be Действительно, существует также операция [** MapReduce **] (http://docs.mongodb.org/manual/core/map-reduce/), которая делает то же самое, хотя и медленнее, поскольку использует собственные функции JavaScript для его карты и сокращения операций. – chridam

+0

Возможно, это совершенно отдельный вопрос, но, допустим, моя схема выглядит так: http://pastebin.com/3eMDkysM. Можно ли сгруппировать его сначала с помощью 'searchId', а затем' created_at'? Что-то вроде этого: http://pastebin.com/EYLBdDUA –

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