Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 
            }
        }
    }
]);
like image 643
StefK Avatar asked Jun 09 '26 06:06

StefK


2 Answers

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 
            }
        }
    }
]);
like image 76
StefK Avatar answered Jun 10 '26 19:06

StefK


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.

like image 28
Takis Avatar answered Jun 10 '26 18:06

Takis