复制/克隆mongoose文档实例的最简单方法是什么?

时间:2013-08-19 23:50:16

标签: mongodb mongoose instance document

我的方法是获取文档实例,并从实例字段中创建一个新实例。我相信有更好的方法可以做到。

7 个答案:

答案 0 :(得分:62)

以下代码克隆Amelia上面上面的回复中的文档无效

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

您还需要重置d1.isNew = true;,如下所示:

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

答案 1 :(得分:8)

你能澄清“复制/克隆”的含义吗?你打算在数据库中创建一个重复的文档吗?或者你只是想在你的程序中有两个var s,它们有重复数据?

如果您这样做:

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"
            }); 
    });

在这种情况下,xy将是程序中同一文档的两个“副本”。

或者,如果您想将doc的新副本插入到数据库中(尽管我假设使用了不同的_id),那将是这样的:

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

或者,如果您从一开始就这样做,又称您创建了一些文档d1,则只需拨打save两次,而无需设置_id

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

现在将有两个文件具有不同的_id,并且您的数据库中的所有其他字段都相同。

这会澄清一些事情吗?

答案 2 :(得分:1)

因此,许多答案对于简单的文档都适用,但是当您尝试对复杂的文档进行深度克隆时,可能会出现错误情况。

例如,如果有子文档数组,则最终可能会在复制的文档中出现重复的_id,这可能在以后引起细微的错误。

要深深克隆猫鼬文档,我建议尝试类似的操作:

//recursively remove _id fields
function 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();

这将是一种非常安全的方法,它将确保使用保存时新生成的_id字段正确克隆对象的每个部分。

答案 3 :(得分:0)

以下代码来克隆文档:

Model.findById(yourid).exec(
        function(err, doc) {
            var newdoc = new Model(doc);
            newdoc ._id = mongoose.Types.ObjectId();
            newdoc .save(callback);
        }
    );

答案 4 :(得分:0)

对于简单克隆使用此:

Context.findOne({
    _id: context._id
})
    .then(function(c) {
        c._id = undefined;
        c.name = context.name;
        c.address = context.address;
        c.created = Date.now();
        return Context.create(c.toObject());
    }).then(function(c) {
        return res.json({
            success: true,
            context: context
        });
    }).catch(function(err) {
        next(err, req, res);
    });

答案 5 :(得分:0)

我的两分钱:

const doc = await DocModel.findById(id).exec();
const obj = doc.toObject();
delete obj._id;
const docClone = new DocModel(obj);
await docClone.save();

答案 6 :(得分:0)

const cloneDoc = (doc, model)=>{
  const copyDoc = new Model({
    ...doc.toObject(),
    _id: undefined,
  });
  copyDoc.isNew = true;
  return copyDoc;
}