[SERVER-9958] $setOnInsert should allow _id to be set Created: 18/Jun/13  Updated: 28/Oct/15  Resolved: 20/Nov/13

Status: Closed
Project: Core Server
Component/s: Write Ops
Affects Version/s: None
Fix Version/s: 2.5.4

Type: Improvement Priority: Major - P3
Reporter: Gordon Roylance Assignee: Scott Hernandez (Inactive)
Resolution: Done Votes: 6
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
is duplicated by SERVER-10685 $setOnInsert prevents setting the _id Closed
Related
related to SERVER-1351 GLE upserted _id field should always ... Closed
Participants:

 Description   

Allow setting the _id field if an update does an insert (upsert true case).

Original Description:
Unable to specify a custom id for the new record using $setOnInsert when calling findAndModify() or update() with upsert = true using a query that does not include the _id. In our scenario the _id is not known before hand, so an additional query has to be used before calling update() or findAndModity() which breaks the atomic nature of the original query. The query worked fine before we wanted to control the _id. When attempting to call db.col.update(

{"name":"test"}

,{$setOnInsert: {_id:"12345"}},

{upsert: true}

) we receive the error: Mod on _id not allowed. This doesn't make sense since the record is being created and _id should not already exist.



 Comments   
Comment by Scott Hernandez (Inactive) [ 20/Nov/13 ]

This now works in the dev release and soon in 2.6.0 stable release:

> db.blah.update({b:3}, {$setOnInsert:{_id:1, foo:1}}, true)
Update WriteResult({ "ok" : 1, "n" : 1, "upserted" : 1 })
> db.blah.find()
{ "_id" : 1, "b" : 3, "foo" : 1 }
> 

Comment by Tim S [ 28/Oct/13 ]

This is killing me, I find it so hard to figure out how to do atomic operations with mongo and now a poor design choice for $setOnInsert and _id is not being fixed for at least six months.

Comment by Taha Jahangir [ 21/Oct/13 ]

The error message is `Mod on _id is not allowed`, but actually this is not a `modification`, so logically we should allow _id in $setOnInsert.

The real use-case of this issue (for me) is where:

  • we want _id be a random string (not-meaningful, not-enumerable, ...)
  • we call `findAndModify` by query on other field(s)
  • so we want to generate a random _id if it doesn't exist, but we don't know what was it if already exists.
Comment by Scott Hernandez (Inactive) [ 08/Jul/13 ]

If the _id field is known beforehand then using it in the query will produce the desired document/update. There is no workaround if the _id is not a known constant for the document and can be used in the query.

Comment by Scott Hernandez (Inactive) [ 18/Jun/13 ]

Currently $set/$setOnInsert doesn't allow setting the _id field at all.

I have changed this to a feature request since this is the currently designed behavior.

Generated at Thu Feb 08 03:21:54 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.