найдите общее количество магазинов за последние 12 месяцев в монгодбе

#javascript #mongodb #aggregation-framework

Вопрос:

Я хочу найти общее количество магазинов за последние 12 месяцев.

 Sample Collection
{
  _id: '5f3d4e5e01e06f0007335233',
  name: 'Walmart',
  createdAt: '2020-08-22T17:42:09.908 00:00'
}
 

Я могу получить результат новых магазинов за последние 12 месяцев

 Shop.aggregate([{
  $match: {
     createdAt: {
      $gte: {
        $date: {{moment.utc().subtract(12, "months").startOf('day').toISOString()}}
      },
      $lt: {
        $date: {{moment.utc().startOf('day').toISOString()}}
      }
    },
    }
}, {
  $project: {
    dateParts: {
      $dateToParts: { date: '$createdAt' }
    },
    total: true,
  }
}, {
    $group: {
      _id:  {
        month: '$dateParts.month',
        year: '$dateParts.year',
      },
      numShops: { $sum: 1 },
    }
}])
 

И этот запрос возвращает результат примерно такой

 [{
  _id: {
    month:3,
    year:2021
  },
  numShops:62,
}, {
.
.
.
}]
 

Приведенный выше запрос возвращает только новые магазины за последние 12 месяцев, но мне нужно общее количество магазинов до определенного месяца.

Запрос должен возвращать результат примерно такой

 [{
  date: 'Aug-2020',
  numShops: 100,   // Total number of shops until aug-2020
}, {
  date: 'Sep-2020'
  numShops: 230, // Total number of shops until sep-2020
}, ....
]
 

Комментарии:

1. Поделитесь, как выглядит ваша коллекция.

2. @TusharShahi на самом деле я не думаю, что имеет значение, как выглядит коллекция. Я просто хочу, чтобы счет шел по месяцам

3. Итак, дата-это дата создания документа?

4. Да, это дата создания. На самом деле это фиктивный сценарий, который я создал.

5. вы что-нибудь пробовали, можете показать свои исследования? какой тип поля даты вы можете отобразить, в каком формате указана дата в коллекции?

Ответ №1:

MongoDB не вернет месяц в виде строки, эффективный вариант-сделать это на стороне клиента после запроса,

Вы можете сделать это в запросе, чтобы справиться с какой-то ситуацией,

  • $group вы правильно сделали операцию
  • $arrayElemAt чтобы выбрать конкретную строку месяца из предоставленного months массива
  • $toString для преобразования year числа в строку
  • $concat для подготовки date строки
 let months = ["", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
db.collection.aggregate([
  {
    $group: {
      _id: {
        year: { $year: "$createdAt" },
        month: { $month: "$createdAt" }
      },
      numShops: { $sum: 1 }
    }
  },
  {
    $project: {
      _id: 0,
      numShops: 1,
      date: {
        $concat: [
          { $arrayElemAt: [months, "$_id.month"] },
          "-",
          { $toString: "$_id.year" }
        ]
      }
    }
  }
])
 

Игровая площадка