Агрегация MongoDB для добавления пропущенных месяцев между двумя датами после группировки по полю даты - PullRequest
1 голос
/ 07 марта 2020

У меня есть запрос, который возвращает общее количество записей в коллекции за год-месяц, сгруппированных по местоположению. Это возвращает данные именно так, как мне нужно, если у местоположения есть результаты за рассматриваемый год-месяц. Однако можно ли вставить запись за месяц, которая не дала результата? Например, скажем, имеет ли мой $ match диапазон дат от 01-2019 до 12-2019. Я хотел бы иметь все 12 записей за месяц с общим значением по умолчанию: 0. Возможно ли это

Усеченная схема:

  {
    branchId: { type: String, required: true },
    orgId: { type: String, required: true },
    stars: { type: Number, default: 0 },
    reviewUpdatedAt: { type: Date, default: Date.now }
  }

Пример запроса:

[
    {
        $match: {
            stars: { $exists: true, $gte: 1 },
            orgId: '100003'
            reviewUpdatedAt: { $gte: new Date(fromDate), $lte: new Date(toDate) }
        }
    },
  {
    $group: {
      _id: {
        date: {
          $dateToString: {
            format: "%m-%Y",
            date: "$reviewUpdatedAt"
          }
        },
        loc: "$branchId"
      },
      total: {
        $sum: 1
      }
    }
  },
  {
    $group: {
      _id: "$_id.loc",
      reviews: {
        $push: {
          total: "$total",
          "date": "$_id.date"
        }
      }
    }
  }
]

Ответы [ 2 ]

1 голос
/ 07 марта 2020

Сначала я подумал, что этого легко достичь с помощью кода, но даже с MongoDB вы можете сделать это, но с помощью ввода из кода:

Скажем, если ваш fromDate - июнь- 2018 & toDate - июнь-2019, тогда, используя ваш язык программирования, вы можете легко получить все месяцы между этими двумя датами в этом формате мм-гггг . Вы можете попытаться сделать это, используя MongoDB, но я бы предпочел в качестве ввода для запроса.

Запрос:

db.collection.aggregate([
    {
      $group: {
        _id: {
          date: {
            $dateToString: {
              format: "%m-%Y",
              date: "$reviewUpdatedAt"
            }
          },
          loc: "$branchId"
        },
        Total: {
          $sum: 1
        }
      }
    },
    {
      $group: {
        _id: "$_id.loc",
        reviews: {
          $push: {
            Total: "$Total",
            "date": "$_id.date"
          }
        }
      }
    },
    /** Overwrite existing reviews field with new array, So forming new array :: 
     * as you're passing all months between these dates get a difference of two arrays (input dates - existing dates after group)
     * while will leave us with an array of missing dates, we would iterate on that missing dates array &
     * concat actual reviews array with each missing date
     * */
    {
      $addFields: {
        reviews: {
          $reduce: {
            input: {
              $setDifference: [
                [
                  "06-2018",
                  "07-2018",
                  "08-2018",
                  "09-2018",
                  "10-2018",
                  "11-2018",
                  "12-2018",
                  "01-2019",
                  "02-2019",
                  "03-2019",
                  "04-2019",
                  "05-2019",
                  "06-2019"
                ],
                "$reviews.date"
              ]
            },
            initialValue: "$reviews",
            in: {
              $concatArrays: [
                "$$value",
                [
                  {
                    date: "$$this",
                    Total: 0
                  }
                ]
              ]
            }
          }
        }
      }
    }
  ])

Тест: MongoDB-Playground

Ссылка: javascript все месяцы между двумя датами

0 голосов
/ 07 марта 2020

, поэтому сделайте шаг назад и поймите, что вы ищете отображение данных, которых нет в БД ... скажем, нет данных для 3/19. это не проблема mon go, но универсальная для любой базы данных. в вашем случае создается «расписание», возможно, это месяц / год ... а для mon go это документы / коллекция ... это предоставляет базовые данные за каждый месяц для начального совпадения .. к которому присоединяются ($ lookup in mon go) будет иметь значение null для 3/19 ...

, добавление расписания является стандартным в аналитических c приложениях - некоторые поставляются с этой функцией, встроенной как часть их основанного на времени функция аналитики, поэтому базе данных не нужно ничего делать ..... но для этого с помощью общих запросов / отчетов в базах данных mon go и sql необходимо вручную добавить эту коллекцию времени / таблицу

...