Skip to content

Upserted document construction in Update operations ignores valid $eq filters if inside $and clauses #2570

Description

@toptobes

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 })

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions