0

I have a collection that looks like:

{
    "_id" : ObjectId("58b77d1349b2e11c06d9cb8a"),
    "blocks" : [
        {
            "userId" : ObjectId("5893a9a64ce29f0231bd060c"),
            "_id" : ObjectId("58b786c5665532d53c21ac72"),
        }
    ]
}
{
    "_id" : ObjectId("58b77d1349b2e11c06d9cb8c"),
    "blocks" : [
        {
            "userId" : ObjectId("581bbb0422e3911e24ea0276"),
            "_id" : ObjectId("592f2d8f092b3b6e374d9bec"),
        }
    ],
}
{
    "_id" : ObjectId("58b85e16894bf623065a0899"),
    "blocks" : [
        {
            "userId" : ObjectId("56e086538146ecb412f974e9"),
            "_id" : ObjectId("592f2cb506dc59992009424a"),
        }
    ]
}

And I want to sum the number of elements in all "blocks" arrays in the collection, so I choose an aggregation query in the shell:

db.userblocks.aggregate([
    {
        $match: {
            blocks: { $gt: [] }
        }
    },
    {
        $group: {
            _id: null,
            cntArray: {
                $push: { $size: "$blocks" }
            }
        }
    },
    {
        $project: {
            "num_blocks": {
                $reduce: {
                    input: "$cntArray",
                    initialValue: 0,
                    in: { $add: [ "$$value", "$$this" ] }
                }
            }
        }
    }
])

The problem is the aggregation query fails with an error:

Error: command failed: { "ok" : 0, "errmsg" : "invalid operator '$reduce'", "code" : 15999 } : aggregate failed

Looking at the documentation, what I'm doing seem valid, but I can't seem to figure what I've done wrong.

3
  • $reduce is available from 3.4. To check your server version, run db.version() from shell. Btw, You don't need to use $reduce. Please refer to the linked duplicate. Commented Jun 21, 2017 at 21:14
  • Your $group should be { "$group": { "_id": null, "num_blocks": { "$sum": { "$size": $blocks" } } }}. That's it. Also your test for the array does not actually do what you think it does. Instead write { "$match": { "blocks.0": { "$exists": true } } }. Which basically means if it has a 0 index, then in fact it is actually an array with something in it. The $gt expression here is actually comparing the BSON types. Two stages and done. Commented Jun 21, 2017 at 23:36
  • Thanks! All the comments were useful and helped me solve the problem. Commented Jun 22, 2017 at 18:17

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.