Chcę zaktualizować _id
pole jednego dokumentu. Wiem, że to nie jest dobra praktyka. Ale z jakiegoś powodu technicznego potrzebuję go zaktualizować. Jeśli spróbuję go zaktualizować, otrzymuję:
> db.clients.update({ _id: ObjectId("123")}, { $set: { _id: ObjectId("456")}})
Performing an update on the path '_id' would modify the immutable field '_id'
A aktualizacja nie jest wykonywana. Jak mogę to zaktualizować?
duplicate key error
nainsert
linii i nie martwisz się problemem, o którym wspomniał @skelly, najprostszym rozwiązaniem jest po prostu zadzwonićremove
najpierw na linię, a następnie na niąinsert
.doc
Powinien już wydrukowane na ekranie tak, że to będzie łatwe do odzyskania, w najgorszym przypadku, nawet jeśli wkładka nie powiedzie, dla prostych dokumentów.Aby to zrobić dla całej swojej kolekcji, możesz również użyć pętli (na przykładzie Nielsa):
db.status.find().forEach(function(doc){ doc._id=doc.UserId; db.status_new.insert(doc); }); db.status_new.renameCollection("status", true);
W tym przypadku UserId był nowym identyfikatorem, którego chciałem użyć
źródło
list()
jest logiczne, ale w przypadku dużych baz danych może to wyczerpać pamięćW przypadku, gdy chcesz zmienić nazwę _id w tej samej kolekcji (na przykład, jeśli chcesz poprzedzić niektóre _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) {... potrzebne, aby zapobiec nieskończonej pętli, ponieważ forEach wybiera wstawione dokumenty, nawet przy użyciu metody .snapshot () .
źródło
find(...).snapshot is not a function
ale poza tym świetne rozwiązanie. Ponadto, jeśli chcesz zastąpić_id
swój niestandardowy identyfikator, możesz sprawdzić, czydoc._id.toString().length === 24
zapobiec nieskończonej pętli (zakładając, że twoje niestandardowe identyfikatory nie mają również 24 znaków ),Tutaj mam rozwiązanie, które pozwala uniknąć wielu żądań, pętli i usuwania starych dokumentów.
Możesz łatwo utworzyć nowy pomysł ręcznie, używając czegoś takiego jak:
_id:ObjectId()
Ale wiedząc, że Mongo automatycznie przypisze _id, jeśli go brakuje, możesz użyć agregacji, aby utworzyć$project
zawierającą wszystkie pola dokumentu, ale pominąć pole _id. Następnie możesz go zapisać za pomocą$out
Więc jeśli twój dokument to:
{ "_id":ObjectId("5b5ed345cfbce6787588e480"), "title": "foo", "description": "bar" }
Wtedy twoje zapytanie będzie:
db.getCollection('myCollection').aggregate([ {$match: {_id: ObjectId("5b5ed345cfbce6787588e480")} } {$project: { title: '$title', description: '$description' } }, {$out: 'myCollection'} ])
źródło
_id
daną wartość, zamiast pozwolić MongoDB wygenerować inną.Możesz także utworzyć nowy dokument z kompasu MongoDB lub za pomocą polecenia i ustawić żądaną
specific _id
wartość.źródło