У меня есть база данных MongoDB, заполненная данными, и я пытаюсь запросить и получить результаты в течение определенного периода времени, в данном случае недель. Я запрашиваю вот так, что может быть неправильно (?), Чтобы получить все объекты, созданные за последние 6 недель:
let weeklyPie = await Job.aggregate([
{ $match: { createdBy: mongoose.Types.ObjectId(req.user.userId) } },
{
$match: {
dateCreated: {
$gte: moment().week(-6).toDate(),
$lt: moment().startOf('week').toDate(),
},
},
},
]);
Предположительно, это возвращает все мои рабочие места, созданные за последние шесть недель.
Более того, я хочу сгруппировать их по неделям, чтобы все задания, созданные на неделе, скажем, 14 (текущая неделя), возвращались в группу с именем weekOne, задания, созданные на 13 неделе, возвращались в группу с именем weekTwo и так далее в течение предыдущих шести недель, начиная с текущий.
Вот как моя схема выглядит в БД:
{
"_id": "6242dc818cd686716633be36",
"company": "Ledner Inc",
"position": "VP Product Management",
"status": "interview",
"jobType": "part-time",
"jobLocation": "San José de Feliciano",
"dateCreated": "2022-03-27T21:24:36.000Z",
"createdBy": "62399147d817b82f5fe8f927",
"createdAt": "2022-02-16T04:06:46.000Z",
"updatedAt": "2022-04-07T10:51:05.171Z",
"__v": 0,
"interviewTime": "2022-04-20T16:30:00.000Z"
}
Итак, вопросы:
Любые подсказки?
Кажется, вы можете использовать $week
и $group
. Существует простое решение без имен групп:
db.collection.aggregate([
{
$match: {
createdBy: mongoose.Types.ObjectId(req.user.userId),
dateCreated: {
$gte: moment().startOf('week').week(-6).toDate(),
$lt: moment().startOf('week').toDate()
},
}
},
{
"$addFields": {
"week": {$week: "$dateCreated"}
}
},
{
$project: {data: "$$ROOT"}
},
{
$group: {
_id: "$data.week",
week: {$first:"$data.week"},
data: {$push: "$data"}
}
}
])
Для того, чтобы получить что-то похожее на ваши ожидаемые результаты. Вы можете увидеть, как это работает на детская площадка.
Если важно назвать группы «weekOne», «weekTwo», вы можете сделать это, добавив шаг, найдя имя группы недели из заданного списка имен групп:
db.collection.aggregate([
{
$match: {
createdBy: mongoose.Types.ObjectId(req.user.userId),
dateCreated: {
$gte: moment().startOf('week').startOf('week').toDate(),
$lt: moment().startOf('week').toDate()
},
}
},
{
"$addFields": {
"weekNum": {$week: "$dateCreated"},
"currentWeek": {$week: ISODate("2022-04-07T21:24:36.000Z")},
}
},
{
$project: {
data: "$$ROOT",
weeksOrder: [
"WeekOne",
"WeekTwo",
"WeekTree",
"WeekFour",
"WeekFive",
"WeekSix"
],
weekIndex: {$subtract: ["$currentWeek", "$weekNum"]
}
}
},
{
$project: {
data: 1,
weekGroup: {"$arrayElemAt": ["$weeksOrder", "$weekIndex"]}
}
},
{
$group: {
_id: "$weekGroup",
week: {$first: "$weekGroup"},
data: {$push: "$data"}
}
}
])
Как вы можете видеть и на детская площадка
Если хотите, можете пропустить "$addFields"
и просто "$group"
с "_id": {"$week": "$dateCreated"}
.
Пффффф, я имею в виду...🤯 вау! Это было так в точку. Я попробовал с $group, и моим следующим шагом была попытка с $project, так как я часами читал документы, но не понял, что в Mongo также есть опция $addFields. Это именно то, что я искал. ОГРОМНОЕ спасибо! Собираюсь прочитать документы, чтобы лучше понять, что вы сделали.