[SERVER-453] $iset - set fields only on insert when upserting Created: 03/Dec/09  Updated: 18/Nov/13  Resolved: 21/Apr/11

Status: Closed
Project: Core Server
Component/s: Querying
Affects Version/s: 1.1.3
Fix Version/s: None

Type: New Feature Priority: Minor - P4
Reporter: Ian White Assignee: Eliot Horowitz (Inactive)
Resolution: Duplicate Votes: 15
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Depends
depends on SERVER-390 upsert with x.y query misinterpreted ... Closed
Duplicate
duplicates SERVER-340 $setOnInsert modifier for upsert Closed
Participants:

 Description   

It'd be nice if there was the ability to tell Mongo on an upsert, "set this field only if a new document is created".

Example:

db.users.update(

{ foo: 'bar'}

, { $set:

{ baz: 'bap' }

, $iset:

{ create_time: new Date() }

}, true)

You could also imagine an equivalent to only set fields when updating but not inserting, although when updating there are more things you might want to do than just set ($inc, $push, etc), this may need more thought as to best approach. Perhaps $updateonly which can then contain any number of possible modifications, e.g. { $updateonly: { $inc:

{ modifications: 1 }

, $set:

{ modify_time: new Date() }

}



 Comments   
Comment by Daniel Doubrovkine [ 18/Nov/13 ]

In my case I am doing a $set for the same value, I presume I am paying the price for that. It would be useful to know how expensive the operation is. Of course, $insert (from above) is what I mean to do, +1 for that.

Comment by Eliot Horowitz (Inactive) [ 21/Apr/11 ]

SERVER-340

Comment by Tom Wardrop [ 28/Feb/11 ]

I was after a similar thing the other week. I'm writing an object mapper that basically builds a queue of document operations, until a commit method is called. The operations are stored in a hash against the actual operator, e.g. {'$set' =>

{name: 'Bill'}

, '$inc' => {age: 2}}. If the document is new (i.e. if the object mapper doesn't know of an _id), then I obviously need some way to run these operations. The best I could come up with was issuing an insert command, for the sole purpose of generating an _id, and then doing an update so I could apply the queued operations.

So the main use case I see for this is being able to apply modifiers (e.g. $set, $inc, etc) during an insert operation. The above suggestion would accommodate this (not ideal, but a solution none the less).

Comment by Eliot Horowitz (Inactive) [ 20/Feb/11 ]

@keith, yes, if this is part of the update spec it'll work fine with findAndModify

Comment by Keith Branton [ 20/Feb/11 ]

+1 for Matt's suggestion of $insert and $update

Eliot closed SERVER-2595 as a duplicate of this - so presumably this will work with findAndModify as well as update - that was what SERVER-2595 was about.

Comment by Torsten Curdt [ 30/Jul/10 ]

This seems to be a duplicate of http://jira.mongodb.org/browse/SERVER-340

Comment by Matt Mastracci [ 07/Apr/10 ]

I ran into this missing functionality today. An alternative syntax might be something like this (using $insert and $update to gate operations):

db.users.update(

{ foo: 'bar'}

, { $set:

{ baz: 'bap' }

, $insert:

{ create_time: new Date() }

, $update: { $inc:

{"update_count", 1}

} }, true)

Comment by Eliot Horowitz (Inactive) [ 03/Dec/09 ]

i think the solution for upsert will also handle this

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