I am trying to query all documents in a collection that contain specific user data WITHOUT returning all subdocuments (there are a ton of subdocuments)
Example Documents
[
{
"id": 1,
"title": "Document 1",
"users": [
{ "id": "a", "name": "User 1" },
{ "id": "b", "name": "User 1" },
]
},
{
"id": 2,
"title": "Document 2",
"users": [
{ "id": "b", "name": "User 1" },
]
},
{
"id": 3,
"title": "Document 3",
"users": [
{ "id": "a", "name": "User 1" },
{ "id": "b", "name": "User 1" },
{ "id": "c", "name": "User 1" },
]
}
]
Here we have 3 documents in which use with id A is in 2 of them, to Query all documents where user A exists I am doing:
collection.findManyByQuery({
users: {
$elemMatch: {
id: 'a'
}
}
})
This returns me documents with id 1 and 3 which is correct. HOWEVER I am trying to return the documents with ONLY user A object inside the users array so my result would look like this
[
{
"id": 1,
"title": "Document 1",
"users": [
{ "id": "a", "name": "User 1" },
]
},
{
"id": 3,
"title": "Document 3",
"users": [
{ "id": "a", "name": "User 1" },
]
}
]
I have tried $unwind: 'users'
and a couple of filters but have not got the desired result.
CodePudding user response:
Use projection stage.
According to docs:
The projection parameter determines which fields are returned in the matching documents
So using users.$: 1
you are telling mongo: "Return the value from users that matches the criteria". In this case the criteria is id: "a"
.
db.collection.find({
users: {
$elemMatch: {
id: "a"
}
}
},
{
"users.$": 1
})
Example here
Also you can use users.id
into find query like in this example
Maybe is a query more clean, only two lines:
db.collection.find({
"users.id": "a"
},
{
"users.$": 1
})
Edit:
To add more values to output (like title
or id
) you have to add to projection stage. By default projection only return the _id
and the values with 1
or true
.
Check this example