Jamie
Jamie

Reputation: 3051

Get the size of an array of each document in a sub array

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

Answers (1)

Sede
Sede

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

Related Questions