0

Here's the structure part of my collection:

_id: ObjectId("W"),
names: [
    {
        number: 1,
        list: ["A","B","C"]
    },
    {
        number: 2,
        list: ["B"]
    },
    {
        number: 3,
        list: ["A","C"]
    }
    ...
],
...

I use this request:

db.publication.aggregate( [ { $match: { _id: ObjectId("54a1de90453d224e80f5fc60") } }, { $group: { _id: "$_id", SizeName: { $first: { $size: { $ifNull: [ "$names", [] ] } } }, names: { $first: "$names" } } } ] );

but I would now use $size in every documents of my names array.

Is it possible to get this result (where "sizeList" is the result of $size) :

_id: ObjectId("W"),
SizeName: 3,
names: [
    {
        SizeList: 3,
        number: 1,
        list: ["A","B","C"]
    },
    {
        SizeList: 1,
        number: 2,
        list: ["B"]
    },
    {
        SizeList: 2,
        number: 3,
        list: ["A","C"]
    }
    ...
],
...
0

2 Answers 2

4

All you really want here is a $project stage and use $map to alter the contents of the array members:

db.names.aggregate([
    { "$project": {
        "SizeName": { "$size": "$names" },
        "names": { "$map": {
            "input": "$names",
            "as": "el",
            "in": {
                "SizeList": { "$size": "$$el.list" },
                "number": "$$el.number",
                "list": "$$el.list"
            }
        }}
    }}
])

You can alternately process with $unwind and group it all back again, but that's kind of long winded when you have MongoDB 2.6 anyway.

Sign up to request clarification or add additional context in comments.

Comments

0

This isn't necessarily the most efficient way, but I think it does what you're aiming to do:

db.publication.aggregate( [ 
    { $unwind: '$names' },
    { $unwind: '$names.list' },
    { $group: {
        _id: { _id: "$_id", number: "$names.number" },
        SizeList: { $sum: 1 },
        list: { $push: "$names.list" }
      }
    },
    { $group: {
        _id: "$_id._id",
        names: {
            $push: {
                number: "$_id.number",
                list: "$list",
                SizeList: "$SizeList"
            }
        },
        SizeName: {$sum: 1}
      }
    }
]);

2 Comments

You might not have been aware that the $size operator referred to by the OP in their question is a MongoDB 2.6 and greater feature that efficiently reports the size of an array. So it is no longer necessary to unwind arrays just to count the elements.
Yeah, your answer is awesome, Neil - Thanks

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.