|
MongoDB supports atomic, in-place updates as well as more traditional updates for replacing an entire document. update()update() replaces the document matching criteria entirely with objNew. If you only want to modify some fields, you should use the atomic modifiers below. Here's the MongoDB shell syntax for update(): db.collection.update( criteria, objNew, upsert, multi ) Arguments:
save() in the mongo shellThe save() command in the mongo shell provides a shorthand syntax to perform a single object update with upsert: // x is some JSON style object db.mycollection.save(x); // updates if exists; inserts if new save() does an upsert if x has an _id field and an insert if it does not. Thus, normally, you will not need to explicitly request upserts, just use save(). Upsert means "update if present; insert if missing". myColl.update( { name: "Joe" }, { name: "Joe", age: 20 }, true );
Modifier OperationsModifier operations are highly-efficient and useful when updating existing values; for instance, they're great for incrementing a number. So, while a conventional implementation does work: var j=myColl.findOne( { name: "Joe" } ); j.n++; myColl.save(j); a modifier update has the advantages of avoiding the latency involved in querying and returning the object. The modifier update also features operation atomicity and very little network data transfer. To perform an atomic update, simply specify any of the special update operators (which always start with a '$' character) with a relevant update document: db.people.update( { name:"Joe" }, { $inc: { n : 1 } } );
The preceding example says, "Find the first document where 'name' is 'Joe' and then increment 'n' by one."
$inc{ $inc : { field : value } }
increments field by the number value if field is present in the object, otherwise sets field to the number value. $set{ $set : { field : value } }
sets field to value. All datatypes are supported with $set. $unset{ $unset : { field : 1} }
Deletes a given field. v1.3+ $push{ $push : { field : value } }
appends value to field, if field is an existing array, otherwise sets field to the array [value] if field is not present. If field is present but is not an array, an error condition is raised. $pushAll{ $pushAll : { field : value_array } }
appends each value in value_array to field, if field is an existing array, otherwise sets field to the array value_array if field is not present. If field is present but is not an array, an error condition is raised. $addToSet{ $addToSet : { field : value } }
Adds value to the array only if its not in the array already. To add many valuest.update { $addToSet : { a : { $each : [ 3 , 5 , 6 ] } } }
$pop{ $pop : { field : 1 } }
removes the last element in an array (ADDED in 1.1) { $pop : { field : -1 } }
removes the first element in an array (ADDED in 1.1) | $pull{ $pull : { field : _value } }
removes all occurrences of value from field, if field is an array. If field is present but is not an array, an error condition is raised. $pullAll{ $pullAll : { field : value_array } }
removes all occurrences of each value in value_array from field, if field is an array. If field is present but is not an array, an error condition is raised. The $ positional operatorVersion 1.3.4+ only. The $ operator (by itself) means "position of the matched array item in the query". Use this to find an array member and then manipulate it. For example: > t.find()
{ "_id" : ObjectId("4b97e62bf1d8c7152c9ccb74"), "title" : "ABC",
"comments" : [ { "by" : "joe", "votes" : 3 }, { "by" : "jane", "votes" : 7 } ] }
> t.update( {'comments.by':'joe'}, {$inc:{'comments.$.votes':1}}, false, true )
> t.find()
{ "_id" : ObjectId("4b97e62bf1d8c7152c9ccb74"), "title" : "ABC",
"comments" : [ { "by" : "joe", "votes" : 4 }, { "by" : "jane", "votes" : 7 } ] }
Currently the $ operator only applies to the first matched item in the query. For example: > t.find();
{ "_id" : ObjectId("4b9e4a1fc583fa1c76198319"), "x" : [ 1, 2, 3, 2 ] }
> t.update({x: 2}, {$inc: {"x.$": 1}}, false, true);
> t.find();
{ "_id" : ObjectId("4b9e4a1fc583fa1c76198319"), "x" : [ 1, 3, 3, 2 ] }
The positional operator cannot be combined with an upsert since it requires a matching array element. If your update results in an insert then the "$" will literally be used as the field name.
Upserts with ModifiersYou may use upsert with a modifier operation. In such a case, the modifiers will be applied to the update criteria member and the resulting object will be inserted. The following upsert example may insert the object {name:"Joe",x:1,y:1}. db.people.update( { name:"Joe" }, { $inc: { x:1, y:1 } }, true );
There are some restrictions. A modifier may not reference the _id field, and two modifiers within an update may not reference the same field, for example the following is not allowed: db.people.update( { name:"Joe" }, { $inc: { x: 1 }, $set: { x: 5 } } );
Pushing a Unique ValueTo add a value to an array only if not already present: Starting in 1.3.3, you can do update( {_id:'joe'},{"$addToSet": { tags : "baseball" } } );
For older versions, add $ne : <value> to your query expression: update( {_id:'joe', tags: {"$ne": "baseball"}},
{"$push": { tags : "baseball" } } );
Checking the Outcome of an Update RequestAs described above, a non-upsert update may or may not modify an existing object. An upsert will either modify an existing object or insert a new object. The client may determine if its most recent message on a connection updated an existing object by subsequently issuing a getlasterror command ( db.runCommand( "getlasterror" ) ). If the result of the getlasterror command contains an updatedExisting field, the last message on the connection was an update request. If the updatedExisting field's value is true, that update request caused an existing object to be updated; if updatedExisting is false, no existing object was updated. An upserted field will contain the new _id value if an insert is performed (new as of 1.5.4). NotesObject PaddingWhen you update an object in MongoDB, the update occurs in-place if the object has not grown in size. This is good for insert performance if the collection has many indexes. Mongo adaptively learns if objects in a collection tend to grow, and if they do, it adds some padding to prevent excessive movements. This statistic is tracked separately for each collection. BlockingStaring in 1.5.2, multi updates yield occasionally so you can safely update large amounts of data. If you want a multi update to be truly atomic, you can use the $atomic flag. See Also |

PLEASE POST QUESTIONS IN THE USER GROUPS FORUM. Post non-question comments and helpful hints here.
blog comments powered by Disqus