Warlock
Warlock

Reputation: 7471

How to query array elements in mongo so that all nested items pass a given condition?

In Mongo I have data structure like this:

db.elements

{
  id: 1,
  arr: [
    {status: true},
    {status: false}
  ]
},

{
  id: 2,
  arr: [
    {status: true},
    {status: true}
  ]
}

I need to find items where status == true for all elements in arr. I expect to see item with id==2.

BUT

db.elements.find({'arr.status': true})

will return both

Upvotes: 1

Views: 54

Answers (1)

Bertrand Martel
Bertrand Martel

Reputation: 45402

You can perform an aggregate to :

  • $unwind your array
  • $group by $_id and by $arr.status
  • $group by $_id and build an array of all distinct values of status (so it will give you [true,false] or [true] or [false])
  • $match all records that have the former array size == 1 && first element is true

mongo query is :

db.elements.aggregate([{
    "$unwind": "$arr"
}, {
    "$group": {
        "_id": {
            id: "$id",
            value: "$arr.status"
        }
    }
}, {
    "$group": {
        "_id": "$_id.id",
        value: {
            $addToSet: '$_id.value'
        }
    }
}, {
    "$match": {
        "value": {
            "$size": 1,
        },
        "value.0": true
    }
}]);

Here is a demo

Upvotes: 1

Related Questions