代码之家  ›  专栏  ›  技术社区  ›  shingara

如何更新MongoDB文档的ID?

  •  110
  • shingara  · 技术社区  · 14 年前

    我想更新一个文档的MongoDB。我知道这不是一个很好的实践。但由于一些技术原因,我需要更新它。但是如果我尝试更新它,我有:

    > db.clients.update({'_id':ObjectId("4cc45467c55f4d2d2a000002")}, {'$set':{'_id':ObjectId("4c8a331bda76c559ef000004")}});
    Mod on _id not allowed
    

    没有更新。我如何才能真正更新它?

    4 回复  |  直到 6 年前
        1
  •  184
  •   Niels van der Rest    14 年前

    您不能更新它。您必须使用新的 _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")})
    
        2
  •  27
  •   BrazaBR Patrick Wolf    9 年前

    要对整个集合执行此操作,还可以使用循环(基于Niels示例):

    db.status.find().forEach(function(doc){ 
        doc._id=doc.UserId; db.status_new.insert(doc);
    });
    db.status_new.renameCollection("status", true);
    

    在这种情况下,userid是我想要使用的新ID

        3
  •  2
  •   Mark    7 年前

    在这种情况下,您希望重命名同一集合中的\u id(例如,如果您希望给某些\u 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});
       }
    });
    

    如果(doc.\u id.indexof(“2019”)!=0)…… 需要防止无限循环,因为foreach选择插入的文档,即使是通过 .snapshot()。 使用的方法。

        4
  •  0
  •   Florent Arlandis    6 年前

    这里我有一个解决方案,可以避免多次请求,比如循环和旧文档删除。

    您可以轻松地手动创建一个新想法,方法如下: _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'}
        ])