Агрегат MongoDB не группирует документы по дате

У меня есть следующие 3 документа в моей MongoDB:

[Object_id: "tMSfNq9JR85XDaQe5"date: Sun Dec 07 2014 19:50:21 GMT+0800 (HKT)description: "Test" projectid: "S83NEGHnrefvfASrf"totalseconds: 22200__proto__: Object, 

Object_id: "FeyzdMosaXCht8DKK"date: Mon Dec 15 2014 00:00:00 GMT+0800 (HKT)description: "444"projectid: "S83NEGHnrefvfASrf"totalseconds: 3660__proto__: Object, 

Object_id: "cCKByxSdQMHAsRKwd"date: Mon Dec 15 2014 00:00:00 GMT+0800 (HKT)description: "555"projectid: "S83NEGHnrefvfASrf"totalseconds: 3660__proto__: Object]

Я пытаюсь запустить на нем следующий совокупный конвейер, чтобы сгруппировать сумму totalseconds на date, чтобы конечный результат был примерно таким, как показано ниже, но каждый раз, когда я получаю результат как 3 записи точно так же, как входные 3 документа... может кто-нибудь, пожалуйста, скажите мне, что я могу делать неправильно/отсутствует здесь? Спасибо

var pipeline = [
  {$group:
        {_id:{"projectId":"$projectid", "date":"$date"},
         totalHrs:{$sum:"$totalseconds"}
        }
  }
];


 { "Date":"Sun Dec 07 2014 19:50:21 GMT+0800 (HKT)",
   "totalseconds": "22200"
 },
 { "Date":"Sun Dec 15 2014 00:00:00 GMT+0800 (HKT)",
   "totalseconds": "7320"
 }

person MChan    schedule 14.12.2014    source источник


Ответы (1)


Все, что вы предоставляете здесь, — это существующее значение «дата» как часть ключа группировки. Это именно то, что он говорит, и, вероятно, будет очень гранулированным, то есть до миллисекунды.

Здесь вам нужно просто использовать «дневную» часть записанного значения метки времени в поле типа даты. Для этого вы можете использовать операторы даты фреймворка агрегации:

db.collection.aggregate([
    { "$group": {
        "_id": { 
            "projectid": "$projectid",
            "day": { "$dayOfMonth": "$date" },
            "month": { "$month": "$date" },
            "year": { "$year": "$date" }
        },
        "totalseconds": { "$sum": "$totalseconds" }
    }}
])

Или просто используйте математику даты для ваших объектов даты и округлите значения до дня:

db.collection.aggregate([
    { "$group": {
        "_id": { 
            "projectid": "$projectid",
            "date": {
                "$subtract": [
                    { "$subtract": [ "$date", new Date("1970-01-01") ]},
                    { "$mod": [
                        { "$subtract": [ "$date", new Date("1970-01-01") ]},
                        1000 * 60 * 60 * 24
                    ]}
                ]
            }
        },
        "totalseconds": { "$sum": "$totalseconds" }
    }}
])

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

person Neil Lunn    schedule 14.12.2014
comment
Спасибо за вашу помощь. Итак, чтобы сгруппировать по всему полю даты (как у меня было в исходном запросе), не разбивая его при группировке на день/месяц/год, время должно быть одинаковым для всех дат... верно? - person MChan; 15.12.2014
comment
@MChan Дело в том, что вам нужна не вся дата, а только ее часть. Если вы на самом деле не хотите группировать значения даты, которые абсолютно одинаковы (с точностью до миллисекунды), вам просто нужно извлечь что-то вроде части дня, часа или минуты. 2014-12-15 19:50:21 и 2015-12-15 00:00:00 не равны и поэтому не сгруппированы вместе. - person Neil Lunn; 15.12.2014
comment
Я полностью понимаю, что вы имеете в виду, просто я запутался, потому что у меня уже было 2 документа с одинаковой датой: понедельник, 15 декабря 2014 г., 00:00:00 по Гринвичу + 0800 (HKT), как вы можете видеть в моих вопросах, и они не были сгруппированы вместе, поэтому я не уверен, было ли это из-за использования полной даты/времени или чего-то еще? - person MChan; 15.12.2014
comment
@MChan Это потому, что projectid также является частью вашего ключа группировки, и в документах это не то же самое. В противном случае, как я уже сказал, фактическое значение даты равно миллисекундам, независимо от его строкового представления. - person Neil Lunn; 15.12.2014
comment
Поскольку идентификатор проекта точно такой же в трех документах, которые у меня есть, то, как вы объяснили, может быть разница в миллисекунды даже между двумя точными датами. Спасибо - person MChan; 15.12.2014