将MongoDb的_id从字符串更改为ObjectId

6
我们有一些文档最初使用StringObjectIdGenerator类型来存储_id。新数据将使用默认的ObjectIdGenerator保存。我们希望能够通过将_id转换为新数据类型来迁移现有数据。这种方式可行吗?
3个回答

6
是的,更改数据类型是可能的。我们需要找到所有具有字符串id的文档,使用迭代器可以克隆一个文档并更改其_id,在克隆后,我们只需要删除旧文档。
下面是针对小型文档的示例。对于大型集合,您可能需要使用db.collection.initializeUnorderedBulkOp()进行批量插入/删除。
db.i.find({_id : {$type : 2}}). //find all string _id
    forEach(function(d){
        var id = ObjectId(d._id); //_id to ObjectId
        var oldId = d._id; // _id
        d._id = id; 
        db.i.insert(d); // clone doc with new Id
        db.i.remove({ _id : oldId }); // delete old doc
        }
    )

示例

> db.i.insertMany([{},{},{},{_id : "4a5ec389fee4c182f509f3ba"}, {_id : "4b5ec389fee4c182f509f3ba"}])
{
    "acknowledged" : true,
    "insertedIds" : [
        ObjectId("5a5ec9edfee4c182f509f3c9"),
        ObjectId("5a5ec9edfee4c182f509f3ca"),
        ObjectId("5a5ec9edfee4c182f509f3cb"),
        "4a5ec389fee4c182f509f3ba",
        "4b5ec389fee4c182f509f3ba"
    ]
}


> db.i.find()
{ "_id" : ObjectId("5a5ec9edfee4c182f509f3c9") }
{ "_id" : ObjectId("5a5ec9edfee4c182f509f3ca") }
{ "_id" : ObjectId("5a5ec9edfee4c182f509f3cb") }
{ "_id" : "4a5ec389fee4c182f509f3ba" }
{ "_id" : "4b5ec389fee4c182f509f3ba" }


> db.i.find({_id : {$type : 2}}).
... forEach(function(d){
... var id = ObjectId(d._id); 
... var oldId = d._id; 
... d._id = id; 
... db.i.insert(d); 
... db.i.remove({ _id : oldId }); 
... }
... )


> db.i.find()
{ "_id" : ObjectId("5a5ec9edfee4c182f509f3c9") }
{ "_id" : ObjectId("5a5ec9edfee4c182f509f3ca") }
{ "_id" : ObjectId("5a5ec9edfee4c182f509f3cb") }
{ "_id" : ObjectId("4a5ec389fee4c182f509f3ba") }
{ "_id" : ObjectId("4b5ec389fee4c182f509f3ba") }
> 

删除语句应该放在插入语句之前,因为在索引集合中先插入再删除现有文档可能会导致重复索引错误,即唯一索引。 - Udit Bhardwaj

1
db.inventries.find({ _id: { $type: 2 } }).forEach(function (d) { var id = ObjectId(d._id); var oldId = d._id; d._id = id; db.inventries.insert(d); db.inventries.remove({ _id: oldId }); } )


// change inventries => your collection name

在 MongoDB 控制台中输入上述命令。

-1
db.getCollection('Files').find({"_id":{"$exists":true}}).forEach(function(x){ 
    let id;
    try {     
      id = new ObjectId(x._id);  
    } 
    catch (err) {     
     id = new ObjectId();  
   } 
  db.Files.update( { "_id": x._id}, { $set: { _id:id } } );  
 }

)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接