我的方法是获取文档实例,并从实例字段创建一个新实例。我确信有更好的方法来做到这一点。
9 回答
您需要重置d1.isNew = true;
为:
Model.findById(yourid).exec(
function(err, doc) {
doc._id = mongoose.Types.ObjectId();
doc.isNew = true; //<--------------------IMPORTANT
doc.save(callback);
}
);
您能否澄清“复制/克隆”的含义?您是否要尝试在数据库中创建重复文档?或者你只是想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"
});
});
在这种情况下,x
和y
将是您程序中同一文档的两个“副本”。
或者,如果您想将文档的新副本插入数据库(尽管_id
我假设使用不同的副本),则如下所示:
Model.findById(yourid).exec(
function(err, doc) {
var d1 = doc;
d1._id = /* set a new _id here */;
d1.isNew = true;
d1.save(callback);
}
);
或者如果你从一开始就这样做,也就是你创建了一些文档d1
,你可以调用save
两次而不设置_id
:
var d1 = new Model({ name: "John Doe", age: 54 });
d1.save(callback);
d1.save(callback);
现在将有两个文档_id
在您的数据库中具有不同的 ' 和所有其他字段相同。
这是否澄清了一些事情?
因此,这些答案中的很多都适用于简单的文档,但是当您尝试对复杂文档进行深度克隆时,可能会出现错误情况。
例如,如果您有子文档数组,则最终可能会在复制的文档中出现重复的 _id,这可能会导致稍后出现细微的错误。
要对 mongoose 文档进行深度克隆,我建议尝试以下操作:
//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 字段正确克隆。
我的两分钱:
const doc = await DocModel.findById(id);
let obj = doc.toObject();
delete obj._id;
const docClone = new DocModel(obj);
await docClone.save();
以下代码克隆文档:
Model.findById(yourid).exec(
function(err, doc) {
var newdoc = new Model(doc);
newdoc._id = mongoose.Types.ObjectId();
newdoc.save(callback);
}
);
对于简单的克隆使用这个:
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);
});
const cloneDoc = (doc, model)=>{
const copyDoc = new Model({
...doc.toObject(),
_id: undefined,
});
copyDoc.isNew = true;
return copyDoc;
}
您基本上可以使用 .clone() 来获取副本。
const cars = Cars.find();
const carsCopy = cars.clone();
await cars;
await carsCopy;
要将文档复制到同一集合或不同集合中,首先获取(查询)数据并制作数据副本。然后从新列表中删除 _id ,因为您不能从当前数据中删除。这将允许您使用从 mongodb 分配的新 _id 插入新记录
将 searchBy 更改为您尝试查找文档的内容。将 collectionA 和 collectionB 更改为要创建复制到的集合的名称。目前我们正在collectionA中搜索并复制collectionB中的数据
collectionA.find(searchBy).exec(function (err, doc) {
// create a new copy
let newDoc = { ...doc[0] }._doc;
// delete property from new copy (remove _id).
delete newDoc._id;
// insert copy into db
var newdoc = new collectionB(newDoc);
newdoc.save();
});