Easiest way to copy/clone a mongoose document instance? Easiest way to copy/clone a mongoose document instance? mongoose mongoose

Easiest way to copy/clone a mongoose document instance?


The following code to clone documents in Amelia's response above does not work:

Model.findById(yourid).exec(    function(err, doc) {        var d1 = doc;        d1._id = /* set a new _id here */;        d1.save(callback);    });

You also need to reset d1.isNew = true; as in:

Model.findById(yourid).exec(    function(err, doc) {        doc._id = mongoose.Types.ObjectId();        doc.isNew = true; //<--------------------IMPORTANT        doc.save(callback);    });


Can you clarify what you mean by "copy/clone"? Are you going trying to create a duplicate document in the database? Or are you just trying to have two vars in your program that have duplicate data?

If you just do:

Model.findById(yourid).exec(    function(err, doc) {         var x = doc;         Model.findById(yourid).exec(            function(err, doc2) {                var y = doc2;                // right now, x.name and y.name are the same                x.name = "name_x";                y.name = "name_y";                console.log(x.name); // prints "name_x"                console.log(y.name); // prints "name_y"            });     });

In this case, x and y will be two "copies" of the same document within your program.

Alternatively, if you wanted to insert a new copy of the doc into the database (though with a different _id I assume), that would look like this:

Model.findById(yourid).exec(    function(err, doc) {        var d1 = doc;        d1._id = /* set a new _id here */;        d1.save(callback);    });

Or if you're doing this from the outset, aka you created some document d1, you can just call save twice without setting the _id:

var d1 = new Model({ name: "John Doe", age: 54 });d1.save(callback);d1.save(callback);

There will now be two documents with differing _id's and all other fields identical in your database.

Does this clarify things a bit?


So, a lot of these answers will work well for simple docs, but there could be an error case when you're trying to make a deep clone of complex documents.

If you have arrays of subdocs, for example, you can end up with duplicate _ids in your copied document, which can cause subtle bugs later.

To do a deep clone of a mongoose doc, I suggest trying something like:

//recursively remove _id fieldsfunction cleanId(obj) {    if (Array.isArray(obj))        obj.forEach(cleanId);    else {        delete obj['_id'];        for (let key in obj)            if (typeof obj[key] == 'object')                cleanId(obj[key]);    }}let some_doc = await SomeModel.findOne({_id: some_id});let new_doc_object = cleanId(some_doc.toObject());let new_doc = new SomeModel(new_doc_object);await new_doc.save();

This is going to be a pretty safe approach, and will ensure that every part of your object is cloned properly with newly generated _id fields on save.