-
Type: Bug
-
Resolution: Works as Designed
-
Priority: Major - P3
-
None
-
Affects Version/s: 3.6.4
-
Component/s: Write Ops
-
None
-
ALL
-
As stated in the docs:
The update creates the new document with [...] the fields and values of both the <query> and <update> parameters if the <update> parameter contains update operator expressions. The update creates a base document from the equality clauses in the <query> parameter, and then applies the update expressions from the <update> parameter.
So of course, this fails:
db.empty.update({"list": "value"}, {"$push": {list: "value", {upsert: 1});
with
The field 'list' must be an array but is of type string in document {no id}
The workaround, suggested in https://jira.mongodb.org/browse/SERVER-20203 is to add an $elemMatch to the query, so that the upserted document is not "pre-filled" with a scalar value for the list key.
But this does not work here: $elemMatch refuses to match single values, so:
db.empty.update({"list": {"$elemMatch": "value", {"$push": {list: "value"}}, {upsert: 1});}}
yields
$elemMatch needs an Object
If I remember correctly, a working workaround used to be:
db.empty.update({"list": {"$in": ["value"], {"$push": {list: "value"}}, {upsert: 1});}}
in 3.2 or 3.4 ; but $in with single value arrays are considered equality matches in 3.6 (i'm guessing here), and this last option fails with
The field 'list' must be an array but is of type string in document {no id}
again.
The only way I found to do this is
db.empty.update({"list": {$in: ["value", "___wrong"], {"$push": {list: "value"}}, {upsert: 1});}}
but this seems very inefficient and I would like to have a cleaner option
- duplicates
-
SERVER-6566 Support conditional updates: $updates
- Closed
- is related to
-
SERVER-20203 upsert querying an array field and $push-ing to that same field yields confusing error
- Closed