MongoDB aggregate by field exists
The $exists
operator is a "query" operator, so it is used basically to "filter" results rather than identify a logical condition.
As a "logical" operator the aggregation framework supports the $ifNull
operator. This returns the field value where it exists or the alternate supplied value where it does not or otherwise evaluates to null
db.test.aggregate([
{ "$group": {
"_id": { "$ifNull": [ "$field", false ] },
"count": { "$sum": 1 }
}}
])
But of course, even that is not a "true/false" comparison, so unless you actually want to return the actual value of the field where it is present, then you are probably better off with a $cond
statement much like you have:
db.test.aggregate([
{ "$group": {
"_id": { "$cond": [{ "$eq": [ "$field", null ] }, true, false ] },
"count": { "$sum": 1 }
}}
])
Where $ifNull
can be very useful is in replacing not existent array fields that would otherwise cause an error using $unwind
. You can then do something like return a single element or empty array so this does not cause problems in the rest of your pipeline processing.
Dunno how it was but now in 2019 there is clean solution. In aggregation pipeline do this
$match: {"my_field": {$ne: null}}
Nice thing is in my lang 'ne' means not :)
I solved it with checking for undefined
$ne : [$var_to_check, undefined]
or
$ne: [ { $type : "$var_to_check"}, 'missing'] }
This returns true if the var is defined
I solved the same problem just last night, this way:
> db.test.aggregate({$group:{_id:{$gt:["$field", null]}, count:{$sum:1}}})
{ "_id" : true, "count" : 2 }
{ "_id" : false, "count" : 2 }
See http://docs.mongodb.org/manual/reference/bson-types/#bson-types-comparison-order for a full explanation of how this works.
Added From comment section:
To check if the value doesn't exist or is null use { $lte: ["$field", null] }