-
Type: Bug
-
Resolution: Unresolved
-
Priority: Critical - P2
-
None
-
Affects Version/s: None
-
Component/s: Querying
-
Query Execution
-
ALL
A fun fact about our query language which I recently learned is that {$ne: null} doesn't necessarily return a subset of what {$exists: true} returns:
db.c.insert({a: [1, {c: 1}]}); db.c.insert({a: [1]}); db.c.find({"a.b": {$exists: true}}) // Returns nothing. db.c.find({"a.b": {$ne: null}}) // Returns {a: [1]} !!!!
When we create a partial index using a filter {$exists: true}, we do not respect these semantics for {$ne: null}:
db.d.drop(); db.d.createIndex( { "a.b": 1 }, { partialFilterExpression: { "a.b": { $exists: true } } } ); db.d.insert({a: [1]}); const query = {"a.b": {$ne: null}}; print("Running the query " + tojson(query) + " with a partial index present"); print("Results are " + tojson(db.d.find(query).toArray())); // (1) print("Dropping the index"); db.d.dropIndexes(); print("Results from the same query are now " + tojson(db.d.find(query).toArray())); // (2)
The results from (1) will be different than those from (2).
I think the bug is here. This code basically says "{$ne: null} is a subset of {$exists true}".
- related to
-
SERVER-36681 Change {$ne: null} semantics to be more intuitive
- Backlog