I have a document containing nested array data. I tried hopelessly to filter the data using $elemMatch
but I cannot figure out why it is not working.
{
'id' : 1,
'name' : 'test',
'modules' : [
{
name: 'foo',
mandatory: false,
group: [
{
name: g1
}]
},
{
name: 'bar',
mandatory: false,
group: [
{
name: g2
}]
}]
}
I tried using this query:
db.test.find(
{
modules: {
$elemMatch: {
name: "foo",
}
}
}
But it keeps returning all the modules. If I use mandatory: true
it returns nothing, which seems to indicates it works. Any idea what am I doing wrong? Thanks!
Accessing embedded/nested documents – In MongoDB, you can access the fields of nested/embedded documents of the collection using dot notation and when you are using dot notation, then the field and the nested field must be inside the quotation marks.
The $elemMatch operator matches documents that contain an array field with at least one element that matches all the specified query criteria. If you specify only a single <query> condition in the $elemMatch expression, and are not using the $not or $ne operators inside of $elemMatch , $elemMatch can be omitted.
The $elemMatch Operator of the MongoDB is used to find documents with at least one array field. The finding operation matches the data in the array field with the criteria mentioned with the $elemMatch. $elemMatch is an operator by MongoDB that is used to match elements in an array.
To search the array of object in MongoDB, you can use $elemMatch operator. This operator allows us to search for more than one component from an array object.
Your query is simply returning all docs that contain a modules
element where name == 'foo'
. To use $elemMatch
to filter the output, you need to use it in the projection argument of the find
call instead of part of the query:
db.test.find({}, {modules: {$elemMatch: {name: 'foo'}}})
To combine both concepts, you can reference the index of the array element matched in the query with $
:
db.test.find({modules: {$elemMatch: {name: 'foo'}}}, {'modules.$': 1})
Either way returns:
{
"_id": ObjectId("..."),
"modules": [
{
"name": "foo",
"mandatory": false,
"group": [
{
"name": "g1"
}
]
}
]
}
If you need other fields included in the output, add them to the projection object (e.g. name: 1
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With