Answers:
您无法更新。您必须使用new来保存文档_id
,然后删除旧文档。
// store the document in a variable
doc = db.clients.findOne({_id: ObjectId("4cc45467c55f4d2d2a000002")})
// set a new _id on the document
doc._id = ObjectId("4c8a331bda76c559ef000004")
// insert the document, using the new _id
db.clients.insert(doc)
// remove the document with the old _id
db.clients.remove({_id: ObjectId("4cc45467c55f4d2d2a000002")})
duplicate key error
的insert
线,而不是担心@skelly提到的问题,最简单的办法是只调用remove
第一行,然后调用insert
线。本doc
应该已经印在屏幕上,因此会很容易恢复,最坏的情况下,即使插入失败,为简单的文档。
为此,您还可以使用循环(基于Niels示例):
db.status.find().forEach(function(doc){
doc._id=doc.UserId; db.status_new.insert(doc);
});
db.status_new.renameCollection("status", true);
在这种情况下,UserId是我要使用的新ID
list()
是合乎逻辑的,但是对于大型数据库,这可能会耗尽内存
如果您想在同一集合中重命名_id(例如,如果要给某些_id加上前缀):
db.someCollection.find().snapshot().forEach(function(doc) {
if (doc._id.indexOf("2019:") != 0) {
print("Processing: " + doc._id);
var oldDocId = doc._id;
doc._id = "2019:" + doc._id;
db.someCollection.insert(doc);
db.someCollection.remove({_id: oldDocId});
}
});
if(doc._id.indexOf(“ 2019:”)!= 0){...需要防止无限循环,因为forEach会选择插入的文档,甚至使用.snapshot()方法也是如此。
find(...).snapshot is not a function
但是除此之外,很棒的解决方案。另外,如果您要替换_id
为自定义ID,则可以检查是否doc._id.toString().length === 24
防止无限循环(假设您的自定义ID的长度也不是24个字符),
在这里,我有一个避免重复请求和循环删除旧文档的解决方案。
您可以使用类似以下的命令轻松地手动创建一个新的想法:_id:ObjectId()
但是,如果知道Mongo会自动分配一个_id(如果缺少),则可以使用aggregate创建一个$project
包含文档的所有字段的字段,但是忽略字段_id。然后可以用保存$out
因此,如果您的文档是:
{
"_id":ObjectId("5b5ed345cfbce6787588e480"),
"title": "foo",
"description": "bar"
}
然后您的查询将是:
db.getCollection('myCollection').aggregate([
{$match:
{_id: ObjectId("5b5ed345cfbce6787588e480")}
}
{$project:
{
title: '$title',
description: '$description'
}
},
{$out: 'myCollection'}
])
_id
给定值,而不是让MongoDB生成另一个值。
您还可以从MongoDB指南针或使用命令创建新文档,然后设置所需的specific _id
值。