Как обновить _id одного документа MongoDB? - PullRequest
114 голосов
/ 25 октября 2010

Я хочу обновить _id MongoDB одного документа. Я знаю, что это не очень хорошая практика. Но по какой-то технической причине мне нужно обновить его. Но если я пытаюсь обновить его, у меня есть:

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

И обновление не производится. Как я могу действительно обновить его?

Ответы [ 4 ]

187 голосов
/ 25 октября 2010

Вы не можете обновить его.Вам придется сохранить документ, используя новый _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")})
27 голосов
/ 06 июня 2013

Чтобы сделать это для всей вашей коллекции, вы также можете использовать цикл (на примере 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 голосов
/ 10 марта 2018

В случае, если вы хотите переименовать _id в той же коллекции (например, если вы хотите префиксировать некоторые _ids):

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 () используемого метода.

0 голосов
/ 31 июля 2018

Здесь у меня есть решение, позволяющее избежать множественных запросов на удаление циклов и старых документов.

Вы можете легко создать новую идею вручную, используя что-то вроде: _id:ObjectId() Но зная, что Mongo автоматически назначит _id, еслиотсутствует, вы можете использовать агрегат для создания $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'}
    ])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...