-
Type:
Bug
-
Resolution: Done
-
Priority:
Minor - P4
-
None
-
Affects Version/s: None
-
Component/s: None
-
None
-
Server Triage
-
ALL
-
None
-
None
-
None
-
None
-
None
-
None
-
None
When using findOneAndUpdate - the document automatilly receives the fields specified in the filter (when no documents matches). This is rather unintuitive and weird as this does not work for "logical" filter like {"xy": {$gt: 100}}. This therefore this cannot not ensure that the inserted document actually matches the filter.
db.test.findOneAndUpdate(
{"filter":100},
{"$set": {"test":"value"}},
{"upsert":true}
)

For replace this works (for me) as expected
db.test.findOneAndReplace(
{"filter":100},
{"test":"value"},
{"upsert":true}
)

This difference in behavior doesnt match the documentation in any way. Which is the same documentation for both findOneAndUpdate and findOneAndReplace
| options.upsert | boolean | Optional. Default: false. A boolean that, if true, indicates that MongoDB should insert a new document that matches the query when the query does not match any existing documents in the collection. |
https://www.mongodb.com/docs/atlas/atlas-ui/triggers/functions/api/#collectionfindoneandreplace
In my opinion the filter should not be added to the document automatically, but rather have an option to validate the newly inserted document against the filter (with a new error code).