In MongoDB, you can use db.collection.save({_id:'abc'}, objectToSave) to perform an upsert.
Let's define objectToSave as below
{_id:'abc', field1:1, field2:2};
In my collection, I have already have a document with same _id value as below:
{_id:'abc', field3:3};
The save function above will replace the existing document in collection to
{_id:'abc', field1:1, field2:2};
What I want is to perform a $set operation to produce some document in collection as below
{_id:'abc', field1:1, field2:2, field3:3};
Can this be achieved in the save function or I have to write separate update statements?
Note that objectToSave's fields are dynamic. The language I'm using is Node.JS.
db.collection.update({'_id':'abc'},{$set:{field1:1,field2:2}},{upsert:true})
should do what you want:
It upserts, so if the document does not exist yet, it is created as {_id:'abc',field1:1,field2:2} and efficiently so, since an index is used which must exist
If the document already exists, the fields field1 and field2 are set to the value in the update statement.
If either of the fields exist in the document, it will be overwritten.
Since you didn't state what language you use: in plain mongoDB, there is no save function. The explicit requirement to merge new and persisted versions of entities is quite an unusual one, so yes, I'd assume that you have to write a custom function.
Related
when I am inserting a document to MongoDB collection I get an error: E11000 duplicate key error collection
I would like to override the existing document with a new one.
Is there any way to force insert new data with the same _id field?
I am using go
You cannot insert two separate documents in MongoDB with the same _id field. This is stated in the documentation on document structure:
The field name _id is reserved for use as a primary key; its value must be unique in the collection, is immutable, and may be of any type other than an array.
What you're describing sounds more like an upsert, an operation that updates a document if it exists, and if it does not, inserts it instead. You could accomplish this by using updateOne and setting the upsert flag to true.
We have two documents that have merged and they now have one one ObjectId.
There exists a configuration document that may have references to the old ObjectId. The old ObjectID can exist all over this document which is full of nested arrays and lists.
We want to do a simple find and replace on this document, preferably without replacing the entire document itself.
Is there a generic way to set every field that has ObjectIdA as a value and replace it with ObjectIdB?
There's no way to do that, no. You need to perform updates on all possible paths explicitly.
How to insert new document in a MongoDB collection if there's no other document with specified unique field exists, or update the existing one otherwise?
Is there anything more reasonable than just using findOne and save methods with some conditions?
While reading about Mongo Save and Update ,I got bit confuse -as per article
MongoDB's update() and save() methods are used to update document into a collection. The update() method update values in the existing document while the save() method replaces the existing document with the document passed in save() method.
Please let me know difference in both .
update changes an existing document found by your find-parameters and does nothing when no such document exist (unless you use the upsert option).
save doesn't allow any find-parameters. It checks if there is a document with the same _id as the one you save exists. When it exists, it replaces it. When no such document exists, it inserts the document as a new one. When the document you insert has no _id field, it generates one with a newly created ObjectId before inserting.
collection.save(document); is basically a shorthand for:
if (document._id == undefined) {
document._id = new ObjectId();
}
collection.update({ "_id":document._id }, document, { upsert:true });
From the documentation:
Save command.
The save() method uses either the insert or the update command, which
use the default write concern. To specify a different write concern,
include the write concern in the options parameter.
If the document does not contain an _id field, then the save() method
calls the insert() method.
If the document contains an _id field, then the save() method is
equivalent to an update with the upsert option set to true and the
query predicate on the _id field.
Update command
if upsert is not specified it
Modifies an existing document or documents in a collection. The method
can modify specific fields of an existing document or documents or
replace an existing document entirely, depending on the update
parameter.
If upsert is true and no document matches the query criteria, update()
inserts a single document.
So they are pretty similar and both can update and insert the document. The difference is that save can update only one document.
While writing data to mongodb, we are checking if the data is present get the _id and using save update it else using insert add the data. Read save is the best way if you are providing _id in the query while saving it will update/insert based on if the _id is present in the db. Is the save the best method or is there any other way.
If you have all data available to save, just run update() each time but use the upsert functionality. Only one query required:
db.collection.update(
['_id' => $id],
$data,
['upsert' => true]
);
If your _id is generated by mongo you always know there is a record in the database and update is the one to use, but then again you could also save().
If you generated your id's (and thus don't know if it comes from the collection), this will always work without having to run an extra query.
From the documentation
db.collection.save()
Updates an existing document or inserts a new document, depending on its document parameter.
db.collection.insert()
Inserts a document or documents into a collection.
If you use db.collection.insert() in your case you will get duplication key error since it will try to insert new document which has same _id with an existing document. But instead of using save you should use the update method.