我有一个名为
students
的mongodb集合,其中有3个文档:
{
_id: ObjectId('66880dd88517a33fd8141e08'),
name: 'Mark',
courses: [
{course_id: ObjectId('6684e9c8122ef4d77a9dfd1a'), active: true},
{course_id: ObjectId('6684e9c8122ef4d77a9dfd1b'), active: false}
]
}
{
_id: ObjectId('668626f11b64d2e86632e7cb'),
name: 'John',
courses: [
{course_id: ObjectId('6684e9c8122ef4d77a9dfd1a'), active: false},
{course_id: ObjectId('6684e9c8122ef4d77a9dfd1b'), active: true}
]
}
{
_id: ObjectId('6684e3b628fcee8f24ead736'),
name: 'Doe',
courses: [
{course_id: ObjectId('6684e9c8122ef4d77a9dfd1a'), active: true},
{course_id: ObjectId('6684e9c8122ef4d77a9dfd1b'), active: true}
]
}
我有另一个名为
courses
的集合,其中有2个文档:
{
_id: ObjectId('6684e9c8122ef4d77a9dfd1a'),
note: 'Course on mongodb.'
}
{
_id: ObjectId('6684e9c8122ef4d77a9dfd1b'),
note: 'Advanced mongodb course.'
}
我想查询课程集合并获取与给定
_id
匹配的所需文档。该文档应包含一个名为 students
的数组。在这个数组中,每个学生应该包含一个 courses
数组,其中只有那些具有与给定 course_id
和 _id
相匹配的 active: true
的课程。
假设给定
_id
是 6684e9c8122ef4d77a9dfd1b
。所以,我想要的输出应该是这样的:
{
_id: ObjectId('6684e9c8122ef4d77a9dfd1b'),
note: 'Advanced mongodb course.',
students: [
{
_id: ObjectId('668626f11b64d2e86632e7cb'),
name: 'John',
courses: [
{course_id: ObjectId('6684e9c8122ef4d77a9dfd1b'), active: true}
]
},
{
_id: ObjectId('6684e3b628fcee8f24ead736'),
name: 'Doe',
courses: [
{course_id: ObjectId('6684e9c8122ef4d77a9dfd1b'), active: true}
]
}
]
}
我正在使用express、mongodb和mongoose。我尝试了这个查询:
app.get('/:id', async function (req, res) {
try {
const batch = await Course.aggregate([
{"$match": {"_id": req.params.id}},
{"$lookup": {
"from": "students",
"localField": "_id",
"foreignField": "courses.course_id",
"as": "students"
}
}
])
res.send(batch)
} catch (error) {
res.json({
error: error
})
}
})
此查询没有提供我想要的输出。如何获得我想要的输出?
您的预期结果是您尝试通过匹配
courses
来过滤 req.params.id
数组中的元素。
您可以使用
$set
管道中的 $lookup
阶段执行过滤器:
db.courses.aggregate([
{
"$match": {
"_id": req.params.id
}
},
{
"$lookup": {
"from": "students",
"localField": "_id",
"foreignField": "courses.course_id",
"pipeline": [
{
$set: {
courses: {
$filter: {
input: "$courses",
cond: {
$eq: [
req.params.id,
"$$this.course_id"
]
}
}
}
}
}
],
"as": "students"
}
}
])