Reputation: 3051
I've a document in the collection 'gyms' which looks like the following:
"name" : "Testing",
"albums" : [
{
"name" : "Aerobics",
"photos" : [
{
"filepath" : "aerobics.jpg"
}
]
},
{
"name" : "Aqua",
"photos" : [
{
"filepath" : "aqua.jpg"
}
]
},
{
"name" : "Zumba",
"photos" : [
{
"filepath" : "zumba.jpg"
}
]
}
],
I'd like to select the amount of photos from each album into the projection.
So my output would look like the following:
"name" : "Testing",
"albums" : [
{
"name" : "Aerobics",
"amount_photos" : 1,
"photos" : [
{
"filepath" : "aerobics.jpg"
}
]
},
{
"name" : "Aqua",
"amount_photos" : 1,
"photos" : [
{
"filepath" : "aqua.jpg"
}
]
},
{
"name" : "Zumba",
"amount_photos" : 1,
"photos" : [
{
"filepath" : "zumba.jpg"
}
]
}
]
It should be achievable with aggregation but i'm getting the following error when I try my query:
The argument to $size must be an Array, but was of type: String
Query:
db.gyms.aggregate(
[
{
$project: {
'albums.photos' : {
amountPhotos: { $size: "photos" }
}
}
}
]
)
Upvotes: 3
Views: 1790
Reputation: 61225
The best and efficient way to do this is using the $map
operator which allows you to return an array of sub-documents with the $size
of the "photos" array.
db.gyms.aggregate(
[
{ "$project": {
"name": 1,
"albums": {
"$map": {
"input": "$albums",
"as": "album",
"in": {
"amount_photos": { "$size": "$$album.photos" },
"name": "$$album.name",
"photos": "$$album.photos"
}
}
}
}}
]
)
Upvotes: 4