[SERVER-340] $setOnInsert modifier for upsert Created: 07/Oct/09 Updated: 07/Mar/14 Resolved: 12/Feb/13 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | Write Ops |
| Affects Version/s: | 1.1.1 |
| Fix Version/s: | 2.4.0-rc1 |
| Type: | New Feature | Priority: | Major - P3 |
| Reporter: | gf | Assignee: | Alberto Lerner |
| Resolution: | Done | Votes: | 65 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||||||||||||||||||||||||||||||||||||||
| Participants: | |||||||||||||||||||||||||||||||||||||||||
| Description |
|
This will set the fields specified in $setOnInsert: {<fields>}if the update results in an insert. It does nothing if any existing documents are updated. |
| Comments |
| Comment by Nik Shornikov [ 27/Feb/13 ] | ||||||||||||
|
@Scott Nichol +1 | ||||||||||||
| Comment by auto [ 07/Feb/13 ] | ||||||||||||
|
Author: {u'date': u'2013-02-07T21:53:24Z', u'email': u'alerner@10gen.com', u'name': u'Alberto Lerner'}Message: | ||||||||||||
| Comment by Scott Hernandez (Inactive) [ 31/Jan/13 ] | ||||||||||||
|
The implementation in 2.3.2 is actually what "$setIfAbsent" should be and not the correct behavior of $setOnInsert. | ||||||||||||
| Comment by Alberto Lerner [ 12/Dec/12 ] | ||||||||||||
|
Already discussed documentation needs with Sam. | ||||||||||||
| Comment by auto [ 12/Dec/12 ] | ||||||||||||
|
Author: {u'date': u'2012-12-12T16:46:47Z', u'email': u'alerner@10gen.com', u'name': u'Alberto Lerner'}Message: | ||||||||||||
| Comment by Stephen Cuppett [ 17/Sep/12 ] | ||||||||||||
|
That's why I believe setIfAbsent is a better solution. | ||||||||||||
| Comment by Ben Polidore [ 17/Sep/12 ] | ||||||||||||
|
Wait, if you do an upsert and put the _id in the query, it will set the id on the "upserted" document to that which you searched. | ||||||||||||
| Comment by Ben Polidore [ 17/Sep/12 ] | ||||||||||||
|
This feature is valuable. Any chance of getting implemented? | ||||||||||||
| Comment by Stephen Cuppett [ 06/Sep/12 ] | ||||||||||||
|
I have effectively implemented a variant of this feature as $setIfAbsent in pull request #298 (https://github.com/mongodb/mongo/pull/298). It appears to satisfy the use case. | ||||||||||||
| Comment by Scott Nichol [ 24/Apr/12 ] | ||||||||||||
|
I am one day into my first MongoDB project and already have a definite need for this capability. It is disconcerting that this has been open since 2009 when it is so useful. | ||||||||||||
| Comment by Glenn Maynard [ 09/Apr/12 ] | ||||||||||||
|
Rather than "$setOnInsert", this should be "$onInsert". For example,
This allows using the same code to generate change lists, eg.:
They can share code much more easily, since you don't need separate code to generate {last_date: new Date(), uses: 1}in the second case. | ||||||||||||
| Comment by Bryan Absher [ 10/Feb/12 ] | ||||||||||||
|
I think that there is enough of a need that this should be done now, whether there is a patch or not. | ||||||||||||
| Comment by Philipp Heinze [ 07/Feb/12 ] | ||||||||||||
|
If there's already some code ready for inclusion into trunk this should be added asap. I don't feel that this new operator would clutter the code more than it's already and if so I'm not sure if this added functionality isn't worth it. Additionally as no refactoring of the current implementation happened for over a year, i don't feel that a refactoring (which seems not to happen in the very near future) should block the implementation of new operators, which are quite much wanted from the community. | ||||||||||||
| Comment by Remon van Vliet [ 26/Jan/12 ] | ||||||||||||
|
By the way, I'm not that fond of $setDef. Although having shorter operator names is generally better this isn't a very clear name. $addField for example is more clear perhaps although I'm sure other suggestions are viable as well. | ||||||||||||
| Comment by Remon van Vliet [ 26/Jan/12 ] | ||||||||||||
|
I'll ask just to be sure; this addition would allow for upserts where the _id field is not of type ObjectID correct? e.g. update( {a:1}, {$setDef:{_id:"myid"}, $set:{b:1}}, true). In fact, it could be argued server generated _id values can be removed completely through this change. The driver can now do this just as it does for insert/save. | ||||||||||||
| Comment by Bryan Absher [ 10/Jan/12 ] | ||||||||||||
|
Is this feature going to be able to make it into the next release? | ||||||||||||
| Comment by Sergey Schetinin [ 03/Nov/11 ] | ||||||||||||
|
$setDef is probably best, but I'll throw in some more options: $addField, $defVal. | ||||||||||||
| Comment by Scott Hernandez (Inactive) [ 03/Nov/11 ] | ||||||||||||
|
$defaults/initial/onInsert maybe? It would good to allow all operators listed in there. | ||||||||||||
| Comment by Seth LaForge [ 03/Nov/11 ] | ||||||||||||
|
The code seems to prefer shorter names. How about $setDef? | ||||||||||||
| Comment by Sergey Schetinin [ 03/Nov/11 ] | ||||||||||||
|
WRT name. In Python such an method on a dict is called setdefault, maybe mongo could use the same name. It's not perfect but much better than $iset IMO. | ||||||||||||
| Comment by Seth LaForge [ 03/Nov/11 ] | ||||||||||||
|
I needed this functionality, so I implemented it myself, ready for merging for 2.1: This supports $iset of _id, as well as other fields. I'm not super keen on the name - "$iset" isn't very clear to me - but I can't think of anything I like better offhand. $new? $setOpt? Yuck. Can this go in for 2.1? I realize from
...but I think that's short-sighted. I agree (after working with it) that this code desperately needs clean-up. However, adding new modifiers doesn't make the code much more complex, those new modifiers would need to be supported after a clean-up anyway. | ||||||||||||
| Comment by Mongo User [ 30/Oct/11 ] | ||||||||||||
|
The $iset should support the definition of the _id value, so that custom ids can be used when an insert is made on an upsert (https://jira.mongodb.org/browse/SERVER-4175). | ||||||||||||
| Comment by Remon van Vliet [ 07/Dec/10 ] | ||||||||||||
|
Voted, assuming Torsten's suggestion is taken into account so that the update is applied on the created document (and specifically the $add-ed fields). | ||||||||||||
| Comment by Rithish [ 03/Nov/10 ] | ||||||||||||
|
This issue is still marked as open. Any timeline for this to come into production? | ||||||||||||
| Comment by Eliot Horowitz (Inactive) [ 26/Jun/10 ] | ||||||||||||
|
Yes - something like that. You can fork and commit on github. Might be another case, but tests would show quickly | ||||||||||||
| Comment by Torsten Curdt [ 26/Jun/10 ] | ||||||||||||
|
Shouldn't this be something along the lines of... diff --git a/db/update.cpp b/db/update.cpp namespace mongo {
@@ -94,6 +94,14 @@ namespace mongo { break; }+ case ADD: { + break; case Mod::PUSH: (Sorry, untested as it doesn't build for me yet) | ||||||||||||
| Comment by Torsten Curdt [ 17/Jun/10 ] | ||||||||||||
|
Would be great to be able to combine these two operations into a single upsert [code] 'first_at' => time, 'last_at' => time, "#{year}" => 1, }) @totals.update({'_id' => track_id} , { '$inc' => { "#{year}" => 1 }, }) [code] so "first_at" only gets set on the first insert [code] @totals.update({'_id' => track_id}, { '$add' => { 'first_at' => time }, '$set' => { 'last_at' => time } , " => 1 }, ) | ||||||||||||
| Comment by gf [ 19/Oct/09 ] | ||||||||||||
|
Good thought! $add - to add indendantly and $addbunch - to add if all of properties doesn't exist. | ||||||||||||
| Comment by Jason Sachs [ 12/Oct/09 ] | ||||||||||||
|
suggest clarifying the description... "adds new properties only if it doesn't exist yet." Does this mean that each property is added only if that property does not exist, and that this decision is made independently for each key in $add's value? (that's what I think you mean) Or that they all get added only if all of them do not exist? |