We have a collection of elements that has the following structure:
elements:
{
id : 123,
items : [ { color: "blue", "groups" : [3, 5] }, { color: "red", "groups" : [6, 8] } ]
}
{
id : 124,
items : [ { color: "blue", "groups" : [1, 2] }, { color: "green", "groups" : [5, 9] } ]
}
We want an efficient way to get Elements that have an item with color blue accessible to groups 5, 9, 27, 123 or 56. This should return Element with id 123 but not element with id 124 because item must meet both conditions. We want the query to be as efficient as possible.
This query is efficient but does not meet the requirement:
{$and : { "items.groups" : { $in : [5, 9, 27, 123, 56] }, "items.color" : "blue" }}
as it will match id = 124
because it has an item that matches "blue" and another one that matches group 9.
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.
Use $match With $eq to Find Matching Documents in an Array in MongoDB. Use $match With $all to Find Matching Documents in an Array in MongoDB.
The $pullAll operator removes all instances of the specified values from an existing array. Unlike the $pull operator that removes elements by specifying a query, $pullAll removes elements that match the listed values.
You need to use $elemMatch
because you're looking to match multiple attributes of a single array element:
db.test.find({ items: { $elemMatch: {
color: "blue",
groups: { $in: [5, 9, 27, 123, 56] }
}}});
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