Select MongoDB documents where a field either does not exist, is null, or is false?

sffc picture sffc · Mar 10, 2014 · Viewed 18.7k times · Source

Suppose I have a collection that contains the following documents:

{ "_id": 1, name: "Apple" }
{ "_id": 2, name: "Banana", "is_reported": null }
{ "_id": 3, name: "Cherry", "is_reported": false }
{ "_id": 4, name: "Kiwi",   "is_reported": true }

Is there a simpler query to select all documents where "is_reported" is in a falsy state; that is, either non-existent, null, or false? That is, a query that selects Apple, Banana, and Cherry, but not Kiwi?

According to the MongoDB FAQ, { "is_reported": null } will select documents where "is_reported" is either null or nonexistent, but it still doesn't select documents where "is_reported" is false.

Right now I have the following query, which works fine, but it just doesn't seem very elegant. If there are multiple fields that I need to select on, it gets messy very fast. Is there a better query that achieves the same end result?

db.fruits.find({ $or: [ { "is_reported": null }, { "is_reported": false } ] })

Answer

JohnnyHK picture JohnnyHK · Mar 10, 2014

You can do this with $in:

db.fruits.find({is_reported: {$in: [null, false]}})

returns:

{
  "_id": 1,
  "name": "Apple"
}
{
  "_id": 2,
  "name": "Banana",
  "is_reported": null
}
{
  "_id": 3,
  "name": "Cherry",
  "is_reported": false
}

You could also flip things around logically and use $ne if you don't have any values besides true to exclude:

db.fruits.find({is_reported: {$ne: true}})