Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between db.collectionX.save and db.collectionX.insert

Tags:

mongodb

> itemsA = { attrA : "vA", attrB : "vB" }
{ "attrA" : "vA", "attrB" : "vB" }
> db.collectionA.insert(itemsA)
> db.collectionA.find()
{ "_id" : ObjectId("4e85de174808245ad59cc83f"), "attrA" : "vA", "attrB" : "vB" }
> itemsA
{ "attrA" : "vA", "attrB" : "vB" }


> itemsB = { attrC : "vC", attrD : "vD" }
{ "attrC" : "vC", "attrD" : "vD" }
> db.collectionB.save(itemsB)
> db.collectionB.find()
{ "_id" : ObjectId("4e85de474808245ad59cc840"), "attrC" : "vC", "attrD" : "vD" }
> itemsB
{
    "attrC" : "vC",
    "attrD" : "vD",
    "_id" : ObjectId("4e85de474808245ad59cc840")
}

Here is my observation:

After being inserted into collectionA, the value of itemsA is not modified.

In the contrast, after being stored into collectionB, the value of itemB is changed!

Is there any rule that guides those modifications so that I know what should be expected after a value is either inserted or saved into a collection?

Thank you

like image 931
q0987 Avatar asked Sep 30 '11 15:09

q0987


2 Answers

For save, if you provide _id, it will update. If you don't, it will insert. One neat feature about Mongo's JavaScript shell is if you call a function without the executing parentesis, it will return the implementation. This is useful if you are curious about any of MongoDB's methods and don't feel like sorting through all of the source code!

In the JS shell:

> db.test.save
function (obj) {
    if (obj == null || typeof obj == "undefined") {
        throw "can't save a null";
    }
    if (typeof obj == "number" || typeof obj == "string") {
        throw "can't save a number or string";
    }
    if (typeof obj._id == "undefined") {
        obj._id = new ObjectId;
        return this.insert(obj);
    } else {
        return this.update({_id:obj._id}, obj, true);
    }
}
> db.test.insert
function (obj, _allow_dot) {
    if (!obj) {
        throw "no object passed to insert!";
    }
    if (!_allow_dot) {
        this._validateForStorage(obj);
    }
    if (typeof obj._id == "undefined") {
        var tmp = obj;
        obj = {_id:new ObjectId};
        for (var key in tmp) {
            obj[key] = tmp[key];
        }
    }
    this._mongo.insert(this._fullName, obj);
    this._lastID = obj._id;
}

From this, we can see that save is a wrapper for update and insert.

Functionally, save and insert are very similar, especially if no _id value is passed. However, if an _id key is passed, save() will update the document, while insert() will throw a duplicate key error.

like image 128
Just a learner Avatar answered Oct 18 '22 22:10

Just a learner


For save, if you provide _id, it will update. If you don't, it will insert, that's the differences.

like image 35
BlaShadow Avatar answered Oct 18 '22 23:10

BlaShadow