#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" }
]
}
}
}
])