I have a collection (summary) like this.
{
"id":"summaryid",
"locations": [
{
"id": "loc1",
"datacenters": [
{
"id": "dc1.1",
"clusters": [
{
"id": "cl1.1",
"servers": [
{
"id": "srvr1.1",
"services": [
{
"id": "srvc1.1"
}
]
}
]
}
]
},
{
"id": "dc1.2",
"clusters": [
{
"id": "cl1.2",
"servers": [
{
"id": "srvr1.2",
"services": [
{
"id": "srvc1.2"
}
]
}
]
}
]
}
]
},
{
"id": "loc2",
"datacenters": [
{
"id": "dc2.1",
"clusters": [
{
"id": "cl2.1",
"servers": [
{
"id": "srvr2.1",
"services": [
{
"id": "srvc2.1"
}
]
}
]
}
]
},
{
"id": "dc2.2",
"clusters": [
{
"id": "cl2.2",
"servers": [
{
"id": "srvr2.2",
"services": [
{
"id": "srvc2.2"
}
]
}
]
}
]
}
]
}
]
}
Now I want only the clusters that are for datacenter with id dc1.1. I would like to exclude servers for the clusters.
I have tried using find query with $elemMatch and projections as below.
db.summary.find({}, {"locations": { $elemMatch: { "datacenters._id" :
"dc1.1" } }, "locations.datacenters.clusters":0,
"locations.datacenters.servers":0, "locations.datacentercount" : 0,
"locations.clustercount" : 0, "locations.servercount" : 0}).pretty()
I am still getting all the datacenters instead of just 1 that matches the id. I am not sure if I am doing this right.
Thank you!
$elemMatchinstruction is using"datacenters._id"but the correct path (based on the example document you supplied) is"datacenters.id"findis to find documents, not parts of the documents. Projection applies to all properties unconditionally, and is not the right tool here. You need to use aggregation to retrieve sub-documents.ProjectionOperation projectStage = new ProjectionOperation().andExclude("locations.datacenters.servers", "locations.datacenters.clusters.servers");Exclusion of field locations.datacenters.servers not allowed. Projections by the mongodb aggregation framework only support the exclusion of the _id field!