Yesterday, I was having difficulty creating a MongoDB query for a group membership collection where I wanted to filter groups where the user belongs and having a specific role. Below is the similar data structure.
[
{
name: "Group name 1",
members: [
{ id: "1001", roles: ["Owner"] },
{ id: "1002", roles: ["Member", "Editor"] },
{ id: "1003", roles: ["Member"] },
]
},
{
name: "Group name 2",
members: [
{ id: "1004", roles: ["Owner"] },
]
},
{
name: "Group name 3",
members: [
{ id: "1003", roles: ["Owner"] },
{ id: "1004", roles: ["Member"] },
]
},
]
Let’s say I’m a user with ID 1003
and I wanted to filter groups where I belong to but only if I have the Owner
role.
First Try
I tried this query filter first:
{
"members.id": "1003",
"members.roles": "Owner",
}
I’m expecting to get the Group name 3
result but I also got the Group name 1
as part of the result. It seems that it matches at least one members property to create a match instead of matching both. It makes sense because this property is an array object.
Solution
Today, I finally found the proper filter based on this guide:
https://docs.mongodb.com/manual/reference/operator/query/elemMatch/#mongodb-query-op.-elemMatch
Here is my new filter:
{
members: {
$elemMatch: {
id: "1003",
roles: "Owner"
}
}
}
The query will match the array property if both of the properties in the array of objects matches the specified filter. Looks good so far!
That’s it!