Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongo query: $exist NULL value

I have the following object in a Mongo collection:

{ 
    "active" : true,
    "startDate": Date( 1434355148265 ), // Mon Jun 15 2015 15:59:08 GMT+0800 (HKT)
    "endDate": null,
    "lastFeedSearch": null,
    "lastTopicSearch": null
}

I then try to run the following query, but it doesn't seem to return any objects

{  
   "active":true,
   "$and":[  
        {  
         "$or":[  
            {  
               "startDate":{  
                  "$exists": false
               }
            },
            {  
               "startDate":{  
                  "$lte": "2015-06-16T07:07:30+00:00"
               }
            }
         ]
      },
      {  
         "$or":[  
            {  
               "endDate":{  
                  "$exists": false
               }
            },
            {  
               "endDate":{  
                  "$gte": "2015-06-16T07:07:30+00:00"
               }
            }
         ]
      },
      {  
         "$or":[  
            {  
               "$or":[  
                  {  
                     "lastTopicSearch":{  
                        "$lte": "2015-06-16T06:07:30+00:00"
                     }
                  },
                  {  
                     "lastTopicSearch":{  
                        "$exists": false
                     }
                  }
               ]
            },
            {  
               "$or":[  
                  {  
                     "lastFeedSearch":{  
                        "$lte": "2015-06-16T06:52:30+00:00"
                     }
                  },
                  {  
                     "lastFeedSearch":{  
                        "$exists": false
                     }
                  }
               ]
            }
         ]
      }
   ]
}

As far as I can tell, all these $or conditions should at least match. From what I can tell, it's because the $exists doesn't seem to take null values into account, although the documentation says it should.

like image 359
woutr_be Avatar asked Jun 16 '15 08:06

woutr_be


2 Answers

From MongoDB official $exists docs:

When <boolean> is true, $exists matches the documents that contain the field, including documents where the field value is null. If <boolean> is false, the query returns only the documents that do not contain the field.

In other words, $exists count nulls as valid values. So, {"$exists": false} only matches documents where corresponding field is undefined, not null.

Try matching your fields with null instead:

{
    "lastTopicSearch": null
}

This query will match both null and undefined values.

like image 62
Leonid Beschastny Avatar answered Sep 28 '22 08:09

Leonid Beschastny


The documentation of $exists says:

When <boolean> is true, $exists matches the documents that contain the field, including documents where the field value is null. If is false, the query returns only the documents that do not contain the field.

All your conditions have $exists:false. Your document has the mentioned fields (with a value of null), so the document does not get returned.

Unfortunately you can not to { endDate: null } because that would also match documents where the field doesn't exist (unless the query uses a sparse index for that field).

When your want to find documents where the field is null and you don't want to create a sparse index, search for fields where the type of the field is Null using the $type-operator.

{ endDate : { $type: 10 } }
like image 21
Philipp Avatar answered Sep 28 '22 08:09

Philipp