Монго группа в несколько раз - PullRequest
0 голосов
/ 05 апреля 2019

Давайте предположим, что у меня есть этот набор данных:

{ ValidFrom: "2019-03-25T16:01:55.714+0000", ValidTo: "2019-03-25T16:01:55.714+0000" },    
{ ValidFrom: "2019-03-26T16:01:55.714+0000", ValidTo: "2019-03-25T16:01:55.714+0000" },    
{ ValidFrom: "2019-03-25T16:01:55.714+0000", ValidTo: "2019-03-27T16:01:55.714+0000" }

Я хотел бы видеть этот результат с одним запросом:

{ "Day": "2019-03-25", ValidFromCount: 2, ValidToCount: 2 },    
{ "Day": "2019-03-26", ValidFromCount: 1, ValidToCount: 0 },    
{ "Day": "2019-03-27", ValidFromCount: 0, ValidToCount: 1 }

В настоящее время я написал эту агрегацию, но я застрялсейчас:

 {
     $addFields: {
            ValidFromDay: { $dateToString: { format: "%Y-%m-%d", date: "$ValidFrom" } },
            ValidUntilDay: { $dateToString: { format: "%Y-%m-%d", date: "$ValidUntil" } }
     }
 },
 {
     $group : {
        _id: { FromDate: '$ValidFromDay', ToDate: '$ValidUntilDay' },
        Count: { "$sum": 1 },
     }
 }, 
 {
     $group : {
        _id: null,
        FromDates: { "$addToSet": { "Date": "$_id.FromDate", "FromCount": { "$sum": "$Count" } } },
        ToDate: { "$addToSet": { "Date": "$_id.ToDate", "UntilCount": "$Count" } }
     }
 }

Возможно ли получить результаты, которые я так или иначе ищу?

Ответы [ 2 ]

2 голосов
/ 05 апреля 2019

Вам нужно добавить массив из 2 полей, а не только 2 полей.Это позволит вам раскрутить его и считать по дате:

{
     $addFields: {
            boundary: [
                { day: {$dateToString: { format: "%Y-%m-%d", date: "$ValidFrom" } }, from: 1 },
                { day: { $dateToString: { format: "%Y-%m-%d", date: "$ValidTo" } } , to: 1 }
                ]
     }
},
{
    $unwind: "$boundary"
},
{
    $group: {
        _id: "$boundary.day",
        ValidFromCount: {$sum: "$boundary.from"},
        ValidToCount: {$sum: "$boundary.to"},
    }
}
0 голосов
/ 05 апреля 2019

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

> projector
{
    "$project" : {
        "day" : {
            "$dayOfMonth" : "$ValidFrom"
        },
        "month" : {
            "$month" : "$ValidFrom"
        },
        "year" : {
            "$year" : "$ValidFrom"
        },
        "ValidFrom" : 1
    }
}

Затем $group для создания итогов и подсчета их по отдельным дням с использованием _id из {year, month, day}.

> grouper
{
    "$group" : {
        "_id" : {
            "year" : "$year",
            "month" : "$month",
            "day" : "$day"
        },
        "ValidFromCount" : {
            "$sum" : 1
        },
        "ValidToCount" : {
            "$sum" : 1
        }
    }
}

Наконец, проекция для устранения ложных полей, а также для перевода поля Day в нужный вам формат.

> converter
{
    "$project" : {
        "_id" : 0,
        "Day" : {
            "$concat" : [
                {
                    "$toString" : "$_id.year"
                },
                "-",
                {
                    "$toString" : "$_id.month"
                },
                "-",
                {
                    "$toString" : "$_id.day"
                }
            ]
        },
        "ValidFromCount" : 1,
        "ValidToCount" : 1
    }
}

для запуска просто выполнить (я создал ваши данныев сборе so2):

> db.so2.find()
{ "_id" : ObjectId("5ca75adfd1a64a2919883a8d"), "ValidFrom" : "2019-03-25T16:01:55.714+0000", "ValidTo" : "2019-03-25T16:01:55.714+0000" }
{ "_id" : ObjectId("5ca75adfd1a64a2919883a8e"), "ValidFrom" : "2019-03-26T16:01:55.714+0000", "ValidTo" : "2019-03-25T16:01:55.714+0000" }
{ "_id" : ObjectId("5ca75adfd1a64a2919883a8f"), "ValidFrom" : "2019-03-25T16:01:55.714+0000", "ValidTo" : "2019-03-27T16:01:55.714+0000" }
>
> db.so3.aggregate([projector,grouper,converter])
{ "ValidFromCount" : 1, "ValidToCount" : 1, "Day" : "2019-3-26" }
{ "ValidFromCount" : 2, "ValidToCount" : 2, "Day" : "2019-3-25" }
>

Я не уверен, что предоставленные вами тестовые данные верны, поскольку второй документ, похоже, возвращается во времени, поэтому ValidTo предшествует ValidFrom.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...