While both of the following filters are semantically equivalent, when upserted in an update command, age and key aren't included in the upserted documents due to being inside of $and statements.
"filter": { "$and":[{ "age":12 },{ "key":"k_6a7ab6e493e8f14b314f12a7_0" }] }
"filter": {"age":12, "key":"k_6a7ab6e493e8f14b314f12a7_0 }
This is problematic for clients which provide filter builders, such as Java, C#, and Go, as they use $ands to glue together separate filters:
filter.And(filter.Eq("age", 12), filter.Eq("key", t.Key(0)))
The offending commands are:
Collection.UpdateOne
Collection.UpdateMany
Collection.FindOneAndUpdate
For reference, with Mongo, $anded filters are properly reconstructed inside of documents
$ db.test.updateOne(
{ $and: [{ a: 1 }, { $and: [{ b: 2 }, { c: 3 }] }] },
{ $set: { d: 4 } },
{ upsert: true }
);
$ db.test.findOne();it does indeed upsert the $anded fields:
{ a: 1, b: 2, c: 3, d: 4 }
It probably goes without saying, but non-$eqs and fields in $or are excluded. Explicit $eqs are ofc included, and dot notation works as well.
For validation precedence, both of these rightfully fail:
// MongoServerError: Plan executor error during update :: caused by :: cannot infer query fields to set, path 'a' is matched twice
db.test.updateOne({ $and: [{ a: 1 }, { a: 2 }] }, { $set: { z: 9 } }, { upsert: true })
// MongoServerError: Plan executor error during update :: caused by :: cannot infer query fields to set, both paths 'a.b' and 'a' are matched
db.test.updateOne({ "a.b": 1, a: { c: 2 } }, { $set: { z: 9 } }, { upsert: true })
While both of the following filters are semantically equivalent, when upserted in an update command,
ageandkeyaren't included in the upserted documents due to being inside of$andstatements.This is problematic for clients which provide filter builders, such as Java, C#, and Go, as they use
$ands to glue together separate filters:The offending commands are:
Collection.UpdateOneCollection.UpdateManyCollection.FindOneAndUpdateFor reference, with Mongo,
$anded filters are properly reconstructed inside of documentsIt probably goes without saying, but non-$eqs and fields in $or are excluded. Explicit $eqs are ofc included, and dot notation works as well.
For validation precedence, both of these rightfully fail: