StefK
StefK

Reputation: 674

MongoDB aggregate match non-empty array

I have a collection in a MongoDB that contains a field "events" which is an array. I need to write an aggregate query for this that checks for the events array to not be empty, but can't find a way to do this.

I want something like:

db.collection.aggregate([
    { 
        $match: { 
            events: {
                "$empty": false 
            }
        }
    }
]);

Upvotes: 7

Views: 15513

Answers (2)

Takis
Takis

Reputation: 8705

Query

  • match to test if not-equal with the empty array
    ($size costs O(n) as far as i know so its bad way to check this)

Test code here

*this query looks straight forward way to do it(yours looks more tricky), but i dont know which is faster, if you benchmark it or anyone knows add on comments if you can

aggregate([{"$match":{"$expr":{"$ne":["$events", []]}}}])

If you want to the document to pass, if its other type of array, you can do this.

aggregate(
[{"$match":
  {"$expr":
   {"$cond":
    [{"$isArray":["$events"]}, {"$ne":["$events", []]}, true]}}}]
)

Your solution is fine if you only want to do this and maybe faster, but if you need an aggregation way to do it, you can use this. For example to check if empty outside of a $match.

Upvotes: 2

StefK
StefK

Reputation: 674

After some digging around and having tried several options (including a nasty project of $gte: 0 of the $size followed by a match on that projected field) I eventually found the following makes sense and actually works:

db.collection.aggregate([
    { 
        $match: { 
            "events.0": {
                "$exists": true 
            }
        }
    }
]);

Upvotes: 16

Related Questions