在有两个集合的 MongoDB 中,尝试获取带有“courseCode”的课程。 在课程集合中,“assignedTutors”是课程集合中的 users._id 数组。 想要“assignedTutors”ID 数组来获取用户集合中的用户信息。
问题:使用当前代码,我无法使用“signedTutors”ID 数组获取用户集合中的用户数据。在当前示例中,“assignedTutors”数组中有 3 个用户 ID,我想使用聚合从用户集合中获取用户数据。
如果有更好的方法来做到这一点,我也愿意。
课程合集:
{
"_id": {
"$oid": "66e765c04ce5539d7f7362c2"
},
"courseCode": "ACB123",
"courseName": "ABC",
"courseImgUrl": "https://ABC.png",
"coursePrice": "123",
"assignedTutors": ["66f9a09505e0ca3203870633", "66f9a07e05e0ca3203870630", "66f9a05005e0ca320387062d"],
"description": "This course ABC",
"published": true,
"school": "ABC school"
}
用户收藏:
{
"_id": {
"$oid": "66f9a09505e0ca3203870633"
},
"userName": "tutor3",
"password": "xxx",
"email": "[email protected]",
"userType": "tutor",
"firstName": "Tutor",
"lastName": "Three",
"teachingCourse": ["66f9adbb05e0ca3203870732", "66e765c04ce5539d7f7362c2"],
"certificates": [],
"purchasedCourse": [],
"__v": {
"$numberInt": "0"
}
}
当前代码:
module.exports.getCourseByCode = function (courseCode) {
return new Promise((resolve, reject) => {
Course.aggregate([
{
$match: { courseCode: courseCode }
},
{
$lookup: {
from: 'users',
localField: 'assignedTutors',
foreignField: '_id',
as: 'assignedTutors'
}
},
{
$unwind: '$assignedTutors'
},
{
$lookup: {
from: 'users',
localField: 'assignedTutors._id',
foreignField: '_id',
as: 'assignedTutors.tutorData'
}
},
{
$project: {
_id: 1,
courseCode: 1,
courseName: 1,
courseImgUrl: 1,
coursePrice: 1,
school: 1,
description: 1,
published: 1,
assignedTutors: { $arrayElemAt: ['$assignedTutors', 0] }
}
}
])
.then((courses) => {
console.log(courses)
if (courses.length === 0) {
reject(`Course with code ${courseCode} not found.`);
} else {
resolve(courses[0]);
}
})
.catch((err) => {
reject(`Error while retrieving course with code ${courseCode}: ${err.message}`);
});
});
};
电流输出:
{
"_id": {
"$oid": "66e765c04ce5539d7f7362c2"
},
"courseCode": "ABC123",
"courseName": "Test",
"courseImgUrl": "abc.png",
"coursePrice": "123",
"assignedTutors": ["66f9a09505e0ca3203870633", "66f9a07e05e0ca3203870630", "66f9a05005e0ca320387062d"],
"description": "XYZ.",
"published": true,
"school": "ABC school"
}
我希望它返回课程以及用户集合上分配的导师数据。
{
"_id": {
"$oid": "66e765c04ce5539d7f7362c2"
},
"courseCode": "ABC123",
"courseName": "Test",
"courseImgUrl": "abc.png",
"coursePrice": "123",
"assignedTutors": [{
"_id": {
"$oid": "66f99b8005e0ca32038705f6"
},
"userName": "user1",
"password": "zzz",
"email": "[email protected]",
"userType": "xxx",
"firstName": "userF",
"lastName": "userL",
"teachingCourse": [],
"certificates": [],
"purchasedCourse": [],
"__v": {
"$numberInt": "0"
}
} {
"_id": {
"$oid": "66f99b8005e0ca32038705f6"
},
"userName": "user2",
"password": "zzz",
"email": "[email protected]",
"userType": "xxx",
"firstName": "userF",
"lastName": "userL",
"teachingCourse": [],
"certificates": [],
"purchasedCourse": [],
"__v": {
"$numberInt": "0"
}
}, {
"_id": {
"$oid": "66f99b8005e0ca32038705f6"
},
"userName": "user3",
"password": "zzz",
"email": "[email protected]",
"userType": "xxx",
"firstName": "userF",
"lastName": "userL",
"teachingCourse": [],
"certificates": [],
"purchasedCourse": [],
"__v": {
"$numberInt": "0"
}
}
}],
"description": "XYZ.",
"published": true,
"school": "ABC school"
}
这里的主要问题是您的
assignedTutors
数组包含字符串而不是 ObjectID。因此,查找将 users.assignedTutors
中的字符串与 users._id
中的 ObjectID 进行匹配。
如果这是您可以在数据库中更改的内容,那么您应该这样做。否则,您需要将其转换为查找之前或在查找中使用 let+pipelines。我下面的示例在查找之前转换了字符串。
assignedTutors: { $arrayElemAt: ['$assignedTutors', 0] }
。您的第二个查找有
assignedTutors.tutorData
,因此您需要对其应用
$arrayElemAt
运算符:
assignedTutors: { $arrayElemAt: ["$assignedTutors.tutorData", 0] }
。但是,不清楚为什么你需要它,因为你在第一次查找时就已经有了它,并且你说你想要所有的导师。
db.course.aggregate([
{ $match: { courseCode: courseCode } },
{
$set: {
assignedTutors: {
$map: {
input: "$assignedTutors",
in: { $toObjectId: "$$this" }
}
}
}
},
{
$lookup: {
from: "users",
localField: "assignedTutors",
foreignField: "_id",
as: "assignedTutors"
}
},
{ $unwind: "$assignedTutors" },
{
$lookup: {
from: "users",
localField: "assignedTutors._id",
foreignField: "_id",
as: "assignedTutors.tutorData"
}
},
{
$project: {
_id: 1,
courseCode: 1,
courseName: 1,
courseImgUrl: 1,
coursePrice: 1,
school: 1,
description: 1,
published: 1,
assignedTutors: { $arrayElemAt: ["$assignedTutors.tutorData", 0] }
}
}
])