Подсчет по нескольким полям - PullRequest
2 голосов
/ 05 февраля 2020

Я работаю с mongodb и aggregation-framework. У меня есть следующие данные в базе данных, которые мне нужно отсортировать и сгруппировать по годам

[{
    "_id": "5df537d615a0cd001759f5e4",
    "timeDoneA": {
        "year":2020,
        "day": 5,
        "month": 12
    },
    "timeDoneB": {
        "year": 2020,
        "day": 4,
        "month": 2
    },
    "timeDoneC": {
        "year": 2020,
        "day": 4,
        "month": 2
    },
},
{
    "_id": "5df6595dab96a000174e29d7",
    "timeDoneA": {
        "year": 2020,
        "day": 12,
        "month": 12
    },
    "timeDoneB": {
        "year": 2019,
        "day": 15,
        "month": 12
    },
    "timeDoneC": {
        "year": 2019,
        "day": 15,
        "month": 12
    },
}...etc],

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

2019: {
   timeDoneA: 0,
   timeDoneB: 1,
   timeDoneC: 1
},
2020: {
   timeDoneA: 2,
   timeDoneB: 1,
   timeDoneC: 1
}

Как я могу это сделать что с запросом агрегации?

1 Ответ

0 голосов
/ 05 февраля 2020

Вы можете использовать этап $ facet , чтобы собрать значения года и удалить ненужные поля, затем $ unwind оба из них и, наконец, использовать $ group чтобы сопоставить значения.

Быстрый и грязный пример:

db.aggtest.aggregate([
    {$facet:{
        years:[
            {$group:{ _id:null,
                      listC:{$addToSet: "$timeDoneC.year"},
                      listB:{$addToSet:"$timeDoneB.year"},
                      listA:{$addToSet:"$timeDoneA.year"}}},
            {$project:{ _id:0,
                        list:{$setUnion:["$listA","$listB","$listC"]}}}],
        done:[{$project:{ _id:0,
                          timeDoneA:"$timeDoneA.year",
                          timeDoneB:"$timeDoneB.year",
                          timeDoneC:"$timeDoneC.year"}}]}},
    {$unwind:"$done"},
    {$unwind:"$years"},
    {$unwind:"$years.list"},
    {$group:{ _id:"$years.list",
              timeDoneA:{$sum:{$cond:[{$eq:["$done.timeDoneA","$years.list"]},1,0]}},
              timeDoneB:{$sum:{$cond:[{$eq:["$done.timeDoneB","$years.list"]},1,0]}},
              timeDoneC:{$sum:{$cond:[{$eq:["$done.timeDoneC","$years.list"]},1,0]}}}}])

Проверка этого на ваших образцах данных дает:

{ "_id" : 2020, "timeDoneA" : 2, "timeDoneB" : 1, "timeDoneC" : 1 }
{ "_id" : 2019, "timeDoneA" : 0, "timeDoneB" : 1, "timeDoneC" : 1 }
...