Wie aktualisiere ich ein Mongo-Dokument nach dem Einfügen?


82

Angenommen, ich füge das Dokument ein.

post = { some dictionary }
mongo_id = mycollection.insert(post)

Angenommen, ich möchte ein Feld hinzufügen und es aktualisieren. Wie mache ich das? Das scheint nicht zu funktionieren .....

post = mycollection.find_one({"_id":mongo_id}) 
post['newfield'] = "abc"
mycollection.save(post)

Antworten:


106

In Pymongo können Sie Folgendes aktualisieren:
mycollection.update({'_id':mongo_id}, {"$set": post}, upsert=False)
Der Parameter Upsert wird anstelle einer Aktualisierung eingefügt, wenn der Beitrag nicht in der Datenbank gefunden wird.
Die Dokumentation ist auf der Mongodb-Website verfügbar .

UPDATE Für Version> 3 verwenden Sie update_one anstelle von update :

mycollection.update_one({'_id':mongo_id}, {"$set": post}, upsert=False)


1
@ Elliott - was ist die andere Alternative?
Ajayramesh

29
mycollection.find_one_and_update({"_id": mongo_id}, 
                                 {"$set": {"newfield": "abc"}})

sollte hervorragend für Sie arbeiten. Wenn kein ID-Dokument vorhanden ist, schlägt mongo_iddies fehl, sofern Sie es nicht auch verwenden upsert=True. Dies gibt standardmäßig das alte Dokument zurück. Um den neuen zu bekommen, bestehen Sie return_document=ReturnDocument.AFTER. Alle Parameter sind in der API beschrieben .

Die Methode wurde für MongoDB 3.0 eingeführt. Es wurde um 3.2, 3.4 und 3.6 erweitert.


2
Es funktioniert auch, wenn Sie "_id" für ein anderes Feld wie "Benutzername" fyi
Chris

1
@Chris Wenn Sie "aktuelles Pymongo" sagen, haben diejenigen von uns aus der Zukunft möglicherweise nicht die gleiche Version. Es ist schön, genau zu sein.
Mnebuerquo

@Mnebuerquo das ist ein ausgezeichneter Punkt, den ich sonst nicht gesehen hätte. Wird in zukünftigen Beiträgen tun, danke.
Chris

@ Chris Die Bearbeitung hilft sehr. Vielen Dank! Und danke von Future-Me, wenn ich das vergesse und es noch einmal nachschlagen muss!
Mnebuerquo

22

Ich werde collection.save(the_changed_dict)diesen Weg benutzen . Ich habe das gerade getestet und es funktioniert immer noch für mich. Folgendes wird direkt zitiert aus pymongo doc.:

save(to_save[, manipulate=True[, safe=False[, **kwargs]]])

Speichern Sie ein Dokument in dieser Sammlung.

Wenn to_save bereits eine "_id" hat, wird eine update () (Upsert) -Operation ausgeführt und jedes vorhandene Dokument mit dieser "_id" wird überschrieben. Andernfalls wird eine insert () -Operation ausgeführt. In diesem Fall, wenn manipulate True ist, wird to_save eine "_id" hinzugefügt, und diese Methode gibt die "_id" des gespeicherten Dokuments zurück. Wenn manipulate False ist, wird die "_id" vom Server hinzugefügt, aber diese Methode gibt None zurück.


9

Dies ist eine alte Frage, aber ich bin darauf gestoßen, als ich nach der Antwort gesucht habe, also wollte ich das Update der Antwort als Referenz geben.

Die Methoden saveund updatesind veraltet.

save (to_save, manipulate = True, check_keys = True, ** kwargs) ¶ Speichern Sie ein Dokument in dieser Sammlung.

DEPRECATED - Verwenden Sie stattdessen insert_one () oder replace_one ().

In Version 3.0 geändert: Der Parameter safe wurde entfernt. Übergeben Sie w = 0 für nicht bestätigte Schreibvorgänge.

update (spec, document, upsert = False, manipulate = False, multi = False, check_keys = True, ** kwargs) Aktualisieren Sie ein oder mehrere Dokumente in dieser Sammlung.

DEPRECATED - Verwenden Sie stattdessen replace_one (), update_one () oder update_many ().

In Version 3.0 geändert: Der Parameter safe wurde entfernt. Übergeben Sie w = 0 für nicht bestätigte Schreibvorgänge.

im speziellen Fall des OP ist es besser zu verwenden replace_one.


9

Gemäß der neuesten Dokumentation zu PyMongo mit dem Titel Einfügen eines Dokuments (Einfügen ist veraltet) und dem folgenden defensiven Ansatz sollten Sie Folgendes einfügen und aktualisieren:

result = mycollection.insert_one(post)
post = mycollection.find_one({'_id': result.inserted_id})

if post is not None:
    post['newfield'] = "abc"
    mycollection.save(post)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.