MongoDB convert Select from UNION with Group By with sum - PullRequest
0 голосов
/ 05 августа 2020

Я создаю COVID API в NodeJS, который содержит очень подробную информацию о моей стране.

Из-за огромного счета я решил переписать всю свою базу данных с MySQL на No SQL который для меня более доступен.

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

У меня есть следующий запрос MySQL, который мне нужен преобразовать в Нет SQL.

SELECT count(a.cases) as cases, a.date FROM 
(SELECT date_specimen AS cases, date_specimen AS date from case_informations WHERE (date_specimen <> '' AND date_onset = '') 
UNION ALL
SELECT date_onset AS cases, date_onset AS date FROM case_informations WHERE date_onset <> '') AS a
GROUP BY a.date ORDER BY a.date ASC

Документ:

{
    "_id": {
        "$oid": "5f29a6dcc4ce73be6be928ff"
    },
    "case_code": "C611583",
    "age": 20,
    "age_group": "20-24",
    "sex": "female",
    "date_specimen": "",
    "date_result_release": "2020-04-22",
    "date_rep_conf": "2020-04-24",
    "date_died": "",
    "date_recover": "",
    "removal_type": "recovered",
    "admitted": "no",
    "region_res": "NCR",
    "prov_res": "",
    "city_mun_res": "",
    "city_muni_psgc": "",
    "health_status": "recovered",
    "quarantined": "no",
    "date_onset": "",
    "pregnant_tab": "no",
    "validation_status": "Removal Type is \"Recovered\", but no Recovered Date is recorded\nRemoval Type is \"Recovered\", but no Recovered Date is recorded\nHealth Status is \"Recovered\", but no Date Recovered is recorded\nHealth Status is \"Recovered\", but no Date Recovered is recorded"
}

Это самое близкое, что я могу получить:

collection.aggregate([
            {$project: {date_specimen: 1, date_onset: 1}},
            {$lookup:
                {
                  from: 'case_informations',
                  pipeline: [
                    {$match: {date_specimen: {$exists: true}, date_onset: ''}},
                    {$group: {_id: '$date_specimen', cases: {$sum: 1}}},
                    {$sort: {_id: 1}},
                  ],
                  as: 'a',
                },
            },
            {$lookup:
                {
                  from: 'case_informations',
                  pipeline: [
                    {$match: {date_onset: {$exists: true}}},
                    {$group: {_id: '$date_onset', cases: {$sum: 1}}},
                    {$sort: {_id: 1}},
                  ],
                  as: 'b',
                },
            },
            {$project: {'a': 1, 'b': 1}},
          ]).limit(1);

результат:

{
  _id: 5f29a6dcc4ce73be6be928fc,
a: [
    { _id: '2020-03-04', cases: 1 },
    { _id: '2020-03-06', cases: 8 },
    { _id: '2020-03-07', cases: 48 },
    {...}
   ],
b: [
    { _id: '2020-03-03', cases: 45 },
    { _id: '2020-03-04', cases: 32 },
    { _id: '2020-03-05', cases: 55 },
    {...}
]
}

ожидается:

{
  _id: 5f29a6dcc4ce73be6be928fc,
UnionOfAandC: [
    { _id: '2020-03-03', cases: 45 },
    { _id: '2020-03-04', cases: 33 }, // merge object with same date
    { _id: '2020-03-05', cases: 55 },
    { _id: '2020-03-06', cases: 8 },
    { _id: '2020-03-07', cases: 48 },
    {...},
   ],
}

1 Ответ

1 голос
/ 05 августа 2020

После некоторых проб и ошибок я наконец решил это

await collection.aggregate([
            {$match: {$or: [{'date_onset': {'$ne': ''}}, {'date_specimen': {'$ne': ''}}]}},
            {
              $group: {
                _id: {
                  'date': {
                    $cond: {
                      if: {$eq: ['$date_onset', '']}, then: '$date_specimen', else: '$date_onset',
                    },
                  },
                },
                cases: {$sum: 1},
              },
            },
            {$sort: {'_id.date': 1}},
            {$project: {'_id': 0, 'date': '$_id.date', 'cases': 1}},
          ]);
...