Reputation: 495
I have a subject model:
const subjectSchema = new Schema({
title: String,
syllabus: {
currentChapter: {
heading: String,
topics: [String],
},
chapters: [
{
heading: String,
topics: [String],
},
],
},
});
I am trying to find a document that corresponds to a particular id. So, I can use:
const subject = await Subject.find({ _id: id });
But now I want that in the chapters
array I get only that document that has the heading property equal to "H 1". So I am using $elemMatch (projection).
const subject = await Subject.find(
{ _id: id },
{ syllabus: { chapters: { $elemMatch: { heading: "H 1" } } } }
);
But this is throwing an error.
UnhandledPromiseRejectionWarning: MongoError: Unsupported projection option: syllabus: { chapters: { $elemMatch: { heading: "H
1" } } }
Upvotes: 0
Views: 721
Reputation: 8168
The problem is that you cannot use elemMatch
with nested fields.
"H1"
.Subject.find({_id: id, "syllabus.chapters.heading": "H1"})
: This will give all the docs where the chapters
array contains at least one object with heading
as "H1"
.
But, here chapters
array will contain all the objects present in it.
$
positional operator.The positional $ operator limits the contents of an array to return the first element that matches the query condition on the array. Docs
Subject.find({_id: id, "syllabus.chapters.heading": "H1"}, {"syllabus.chapters.$1": 1})
: This will only keep the first matching object where heading
is equal to "H1"
.
Working Solution: Here
Upvotes: 2
Reputation: 988
You're passing the $elemMatch
condition in the second argument of the find
function. You need to move it to the object in the first argument, at the same level as _id: id
, and change it to "syllabus.chapters": { $elemMatch: { heading: "H 1" } }
.
Here's a working MongoPlayground link
Upvotes: 1