Details
-
Bug
-
Status: Backlog
-
Critical - P2
-
Resolution: Unresolved
-
None
-
None
-
Query Execution
-
ALL
Description
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}".
Attachments
Issue Links
- related to
-
SERVER-36681 Change {$ne: null} semantics to be more intuitive
-
- Backlog
-