Lookup:
const course = await mongoose.model('Course').aggregate()
.match({ _id: new mongoose.Types.ObjectId(id) })
.lookup({
from: 'User',
foreignField: '_id',
localField: 'userId',
as: 'user'
})
Course schema:
const CourseSchema = new Schema({
title: String,
userId: {
type: mongoose.Types.ObjectId,
ref: 'User'
},
}, { strict: false });
Expected output:
{
"course": [
{
"_id": "64b000c085e9b1aec5975249",
"title": "test",
"userId": "64affc47d81a4bfba92b5540",
"user": [], // data here should be present but empty why?
}
]
}
How do I get user data in the above output?
Works using populate:
const course = await mongoose.model('Course')
.find({ _id: new mongoose.Types.ObjectId(id) })
.populate('userId').exec();
But how to achieve this using aggregation pipeline?
2
Answers
If your
userId
inCourse
collection is objectId instead of plain Stringyou can aggregate result by following query,
if you have userId as plain String you need to use
$addFields
to convert your string id to ObjectId.The collection name is
users
, notUser
. See option: collectionLet’s see the
utils.toCollectionName
method:See full source code
As you can see, the model name
'User'
will be converted to the collection name"users"
. So it should befrom: "users"
, notfrom: "User"
inlookup()
method.The
localField
andforeignField
are wrong. ThelocalField
is the field in the local collection which iscources
. TheforeignField
is the field in the foreign collection which isusers
.from: <foreign collection>
localField: <field from local collection's documents>
,foreignField: <field from foreign collection's documents>
A working example:
Logs: