Группировка и суммирование встроенного массива по месяцам - PullRequest
0 голосов
/ 09 сентября 2018

У меня есть следующая схема:

_id 
dates : 
    date :
       year
       month
       day
other unrelated fields

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

_id : 124567789554
dates : 
    date : 
        year : 2018
        month : 9
        day : 1
    date : 
        year : 2018
        month : 9
        day : 2
    date : 
        year : 2018
        month : 9
        day : 3
    date : 
        year : 2018
        month : 10
        day : 1

Вывод, который я хочу получить:

_id : 124567789554
dates : 
    date : 
        year : 2018
        month : 9
        count : 3
    date : 
        year : 2018
        month : 10
        count : 1

Как я могу это сделать?

Редактировать: Для некоторого дополнительного контекста мне сначала нужно сгруппировать по personId Изначально схема выглядит следующим образом:

_Id (automatically generated by mongoDB)
personId 
date

Есть несколько строк с одинаковым personId, соответствующих дате. Я должен сначала сгруппировать так, чтобы _Id = personId, и агрегировать даты вместе. Как я могу сделать оба одновременно? Мой текущий запрос:

{
  _id: "$personId",
  dates: {
    $addToSet: "$date"
  },
  other unrelated fields
}

Ответы [ 2 ]

0 голосов
/ 10 сентября 2018

Используйте $group, чтобы сгруппировать по идентификатору человека, месяцу и году и подсчитать количество совпадений, после чего введите $group, чтобы собрать все даты с указанием года и месяца и подсчитать для каждого идентификатора человека.

db.colname.aggregate([
  {"$group":{
    "_id":{"personId":"$personId","year":"$date.year","month":"$date.month"},
    "count":{"$sum":1}
  }},
  {"$group":{
    "_id":"$_id.personId",
    "dates":{"$push":{"year":"$_id.year","month":"$_id.month","count":"$count"}}
  }}
])
0 голосов
/ 10 сентября 2018

Если вы сохраняете свое поле в формате BSON Date , это легко сделать с помощью группового агрегирования .

Очень похожий пример кода из документа Mongo:

db.sales.aggregate(
   [
      {
        $group : {
           _id : { month: { $month: "$date" }, day: { $dayOfMonth: "$date" }, year: { $year: "$date" } },
           totalPrice: { $sum: { $multiply: [ "$price", "$quantity" ] } },
           averageQuantity: { $avg: "$quantity" },
           count: { $sum: 1 }
        }
      }
   ]
)

Результат:

{ "_id" : { "month" : 3, "day" : 15, "year" : 2014 }, "totalPrice" : 50, "averageQuantity" : 10, "count" : 1 }
{ "_id" : { "month" : 4, "day" : 4, "year" : 2014 }, "totalPrice" : 200, "averageQuantity" : 15, "count" : 2 }
{ "_id" : { "month" : 3, "day" : 1, "year" : 2014 }, "totalPrice" : 40, "averageQuantity" : 1.5, "count" : 2 }
...