Jak zaktualizować dokument Mongo po wstawieniu go?

83

Powiedzmy, że wstawiam dokument.

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

Teraz powiedzmy, że chcę dodać pole i zaktualizować je. Jak mogę to zrobić? To chyba nie działa .....

post = mycollection.find_one({"_id":mongo_id}) 
post['newfield'] = "abc"
mycollection.save(post)
TIMEX
źródło

Odpowiedzi:

108

W pymongo możesz zaktualizować za pomocą:
mycollection.update({'_id':mongo_id}, {"$set": post}, upsert=False)
Parametr Upsert wstawi zamiast aktualizacji, jeśli post nie zostanie znaleziony w bazie danych.
Dokumentacja jest dostępna na stronie mongodb .

UPDATE Dla wersji> 3 użyj update_one zamiast update :

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

allait
źródło
1
@Elliott - jaka jest inna alternatywa?
ajayramesh
29
mycollection.find_one_and_update({"_id": mongo_id}, 
                                 {"$set": {"newfield": "abc"}})

powinien działać znakomicie dla Ciebie. Jeśli nie ma dokumentu o identyfikatorze mongo_id, zakończy się niepowodzeniem, chyba że użyjesz również upsert=True. To domyślnie zwraca stary dokument. Aby zdobyć nowy, zdaj return_document=ReturnDocument.AFTER. Wszystkie parametry są opisane w API .

Metoda została wprowadzona w MongoDB 3.0. Został przedłużony do wersji 3.2, 3.4 i 3.6.

serv-inc
źródło
2
Działa również, jeśli podasz „_id” w innym polu, takim jak „nazwa użytkownika” fyi
Chris,
1
@Chris Kiedy mówisz „obecny pymongo”, przyszli ludzie mogą nie mieć tej samej wersji. Miło jest być konkretnym.
Mnebuerquo
@Mnebuerquo to doskonały punkt, którego inaczej bym nie widział. Zrobi się w przyszłych postach, dzięki.
Chris
@Chris Edycja bardzo pomaga. Dzięki! I dzięki od future-me, kiedy o tym zapomnę i muszę to ponownie sprawdzić!
Mnebuerquo
22

Wykorzystam collection.save(the_changed_dict)ten sposób. Właśnie to przetestowałem i nadal działa. Poniższy cytat pochodzi bezpośrednio z pymongo doc.:

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

Zapisz dokument w tej kolekcji.

Jeśli to_save ma już „_id”, wówczas wykonywana jest operacja update () (upsert) i każdy istniejący dokument z tym „_id” jest nadpisywany. W przeciwnym razie wykonywana jest operacja wstawiania (). W tym przypadku, jeśli manipulate ma wartość True, do to_save zostanie dodany „_id”, a ta metoda zwraca „_id” zapisanego dokumentu. Jeśli manipulacja ma wartość False, serwer doda „_id”, ale ta metoda zwróci wartość None.

Andrew_1510
źródło
9

To jest stare pytanie, ale natknąłem się na to, szukając odpowiedzi, więc chciałem podać aktualizację odpowiedzi w celach informacyjnych.

Metody savei updatesą przestarzałe.

save (to_save, manipulate = True, check_keys = True, ** kwargs) ¶ Zapisz dokument w tej kolekcji.

DEPRECATED - Zamiast tego użyj insert_one () lub replace_one ().

Zmieniono w wersji 3.0: Usunięto bezpieczny parametr. Przekaż w = 0 dla niezatwierdzonych operacji zapisu.

update (spec, document, upsert = False, manipulate = False, multi = False, check_keys = True, ** kwargs) Zaktualizuj dokument (y) w tej kolekcji.

DEPRECATED - Zamiast tego użyj replace_one (), update_one () lub update_many ().

Zmieniono w wersji 3.0: Usunięto bezpieczny parametr. Przekaż w = 0 dla niezatwierdzonych operacji zapisu.

w konkretnym przypadku PO lepiej jest użyć replace_one.

ThinkBonobo
źródło
9

Zgodnie z najnowszą dokumentacją dotyczącą PyMongo zatytułowaną Wstaw dokument (wstawka jest przestarzała) i zgodnie z podejściem obronnym, należy wstawiać i aktualizować w następujący sposób:

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

if post is not None:
    post['newfield'] = "abc"
    mycollection.save(post)
Gürol Canbek
źródło