EDIT: The query should not user the '&" characters. Those or for updates.
ANSWER: Courtesy of Gibbs
correct:
const result : any = await mongoose.model('Events').update(
{
_id: eventId,
"groups._id": groupId,
"groups.users._id": userId
},
incorrect:
const result: any = await mongoose.model('Events').findOne(
{
_id: eventId,
"groups._id": "5f270416e7964b20d6f8953e",
"groups.$.users": { _id: '5f270877b4942d2528885dbd' }
})
// OR:
{
_id: eventId,
"groups._id": "5f270416e7964b20d6f8953e",
"groups.$.users._id" : '5f270877b4942d2528885dbd',
})
With only the first two predicates,( eventId
and groups [$_id]
) it returns the event. But the third breaks.
Does anybody know why this returns null (object ids are copied directly from the db) Thanks!
{
"_id": ObjectId("5f270416e7964b20d6f8953d"),
"lastRounds": [],
"name": "EpicFest",
"start": 1596392488896.0,
"end": 1596392500896.0,
"groups": [
{
"_id": ObjectId("5f270416e7964b20d6f8953e"),
"name": "Vossius",
"users": [
{
"created": 1596393590778.0,
"sessionId": null,
"feedBack": {
"messagesSent": 0,
"messagesSentLiked": 0,
"messagesReceived": 0,
"messagesReceivedLiked": 0,
"userFeedbackReceived": [],
"chatFeedbackReceived": [],
"_id": ObjectId("5f270877b4942d2528885dbe")
},
"_id": ObjectId("5f270877b4942d2528885dbd"),
"image": "someAvatr",
"name": "hans",
"groupId": "5f270416e7964b20d6f8953e",
"results": []
},
]
},
{
"_id": ObjectId("5f270416e7964b20d6f8953f"),
"users": [],
"name": "Ignatius"
}
],
"results": [],
"theses": [],
"rounds": 10,
"schedule": [],
"__v": 4
}
Use the aggregate pipeline to fetch based on the inner sub-document.
In the first match stage, filter by eventId
and do a $elemMatch on the inner groupId
. Next, unwind the group
and groups.user
.
Post unwinding you will have a flat object structure that you can again apply filter upon and, just apply a match stage on groups.user._id
now.
const pipeline = [
{
$match: {
_id: eventId,
groups: {
$elemMatch: mongoose.Types.ObjectId('5f270416e7964b20d6f8953e')
}
}
},
{
$unwind: '$groups'
},
{
$unwind: '$groups.users'
},
{
$match: {
'$groups.users._id': mongoose.Types.ObjectId('5f270877b4942d2528885dbd')
}
}
];
const result: any = await mongoose.model('Events').aggregate(pipeline).exec();
db.collection.find({
_id: ObjectId("5f270416e7964b20d6f8953d"),
"groups._id": ObjectId("5f270416e7964b20d6f8953e"),
"groups.users._id": ObjectId("5f270877b4942d2528885dbd")
})
You tried to use String "5f270416e7964b20d6f8953e"
. It should be ObjectId
You can use .
notation to access a nested element or $elemMatch
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.