202

So I'm attempting to find all records who have a field set and isn't null.

I try using $exists, however according to the MongoDB documentation, this query will return fields who equal null.

$exists does match documents that contain the field that stores the null value.

So I'm now assuming I'll have to do something like this:

db.collection.find({ "fieldToCheck" : { $exists : true, $not : null } })

Whenever I try this however, I get the error [invalid use of $not] Anyone have an idea of how to query for this?

serv-inc
  • 35,772
  • 9
  • 166
  • 188
AlbertEngelB
  • 16,016
  • 15
  • 66
  • 93

8 Answers8

305

Use $ne (for "not equal")

db.collection.find({ "fieldToCheck": { $ne: null } })
Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
45

Suppose we have a collection like below:

{ 
  "_id":"1234"
  "open":"Yes"
  "things":{
             "paper":1234
             "bottle":"Available"
             "bottle_count":40
            } 
}

We want to know if the bottle field is present or not?

Ans:

db.products.find({"things.bottle":{"$exists":true}})
deadshot
  • 8,881
  • 4
  • 20
  • 39
Pavan Choudhary
  • 459
  • 4
  • 2
  • 4
    `When is true, $exists matches the documents that contain the field, including documents where the field value is null.` [From the docs.](http://docs.mongodb.org/manual/reference/operator/query/exists/) – AlbertEngelB Aug 16 '15 at 15:14
  • 1
    yep, but i don' see why a DB would contain the value null, it's sloppy – Martijn Scheffer Aug 13 '16 at 17:56
6

i find that this works for me

db.getCollection('collectionName').findOne({"fieldName" : {$ne: null}})
Yakir Manor
  • 4,687
  • 1
  • 32
  • 25
3

This comment is written in 2021 and applies for MongoDB 5.X and earlier versions.

If you value query performance never use $exists (or use it only when you have a sparse index over the field that is queried. the sparse index should match the criteria of the query, meaning, if searching for $exists:true, the sparse index should be over field:{$exist:true} , if you are querying where $exists:true the sparse index should be over field:{$exist:false}

Instead use :

db.collection.find({ "fieldToCheck": {  $ne: null } })

or

db.collection.find({ "fieldToCheck": {  $eq: null } })

this will require that you include the fieldToCheck in every document of the collection, however - the performance will be vastly improved.

Dror
  • 5,107
  • 3
  • 27
  • 45
  • See my answer: https://stackoverflow.com/a/72843232/1301837. It explains the current limitations of `$exists` with full index and the reason. – Sergei Kuzmin Jul 03 '22 at 00:24
2
db.<COLLECTION NAME>.find({ "<FIELD NAME>": { $exists: true, $ne: null } })
Hardik Gajjar
  • 1,024
  • 12
  • 27
1

In my case, i added new field isDeleted : true to only fields that are deleted.

So for all other records there was no isDeleted field, so i wanted to get all the fields that isDeleted either does not exist or false. So query is

.find({ isDeleted: { $ne: true } });
Sunil Garg
  • 14,608
  • 25
  • 132
  • 189
0

I Tried to convert it into boolean condition , where if document with table name already exist , then it will append in the same document , otherwise it will create one .

table_name is the variable using which i am trying to find the document

query = { table_name : {"$exists": "True"}}
    
    result = collection.find(query)
    flag = 0
    for doc in result:
        collection.update_one({}, { "$push" : { table_name : {'name':'hello'} } } )
        flag = 1
    if (flag == 0):
        collection.insert_one({ table_name : {'roll no' : '20'}})
arpit1714
  • 543
  • 6
  • 8
0

aggregate example

https://mongoplayground.net/p/edbKil4Zvwc

db.collection.aggregate([
  {
    "$match": {
      "finishedAt": {
        "$exists": true
      }
    }
  },
  {
    "$unwind": "$tags"
  },
  {
    "$match": {
      "$or": [
        {
          "tags.name": "Singapore"
        },
        {
          "tags.name": "ABC"
        }
      ]
    }
  },
  {
    "$group": {
      "_id": null,
      "count": {
        "$sum": 1
      }
    }
  }
])
Rafiq
  • 8,987
  • 4
  • 35
  • 35