3

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" } 
            }
         }
      }
   ]
)

1 Answer 1

4

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"  
                    } 
                } 
            } 
        }}
    ]
)
Sign up to request clarification or add additional context in comments.

2 Comments

I thought there would be a more simple way in mongo to do this, apparently not. Thanks!
A shorter way* Like my query.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.