MongoDB aggregate match non-empty array
Asked Answered
A

2

7

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 
            }
        }
    }
]);
Amicable answered 4/2, 2022 at 11:45 Comment(0)
A
16

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 
            }
        }
    }
]);
Amicable answered 4/2, 2022 at 11:45 Comment(0)
R
2

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.

Rothko answered 4/2, 2022 at 11:56 Comment(2)
While this certainly manages to return all events that have at least one event in the array, it also finds documents that have an events value that is not an array. For example when the value would be a String. While this would be an unlikely scenario, this is possible in MongoDB.Amicable
this is fixable, by adding one more check, i guess you can use any way, i havent benchmarked them to tell you what is faster, i will test it sometime.Rothko

© 2022 - 2024 — McMap. All rights reserved.