Làm cách nào để cập nhật tài liệu Mongo sau khi chèn nó?


83

Giả sử tôi chèn tài liệu.

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

Bây giờ, giả sử tôi muốn thêm một trường và cập nhật nó. Làm thế nào để làm điều đó? Điều này dường như không hoạt động .....

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

Câu trả lời:


108

Trong pymongo, bạn có thể cập nhật bằng:
mycollection.update({'_id':mongo_id}, {"$set": post}, upsert=False)
Tham số Upsert sẽ chèn thay vì cập nhật nếu bài viết không được tìm thấy trong cơ sở dữ liệu.
Tài liệu có sẵn tại trang mongodb .

CẬP NHẬT Đối với phiên bản> 3 sử dụng update_one thay vì cập nhật :

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


1
@Elliott - giải pháp thay thế khác là gì?
ajayramesh

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

sẽ làm việc hiệu quả cho bạn. Nếu không có tài liệu của id mongo_id, nó sẽ không thành công, trừ khi bạn cũng sử dụng upsert=True. Điều này trả về tài liệu cũ theo mặc định. Để có được cái mới, hãy vượt qua return_document=ReturnDocument.AFTER. Tất cả các tham số được mô tả trong API .

Phương pháp này đã được giới thiệu cho MongoDB 3.0. Nó đã được mở rộng cho 3.2, 3.4 và 3.6.


2
Nó cũng hoạt động nếu bạn đặt "_id" cho một trường khác như "tên người dùng" fyi
Chris

1
@Chris Khi bạn nói "pymongo hiện tại", những người trong chúng ta từ tương lai có thể không có cùng phiên bản. Thật tuyệt khi được cụ thể.
Mnebuerquo

@Mnebuerquo đây là một điểm tuyệt vời mà tôi không thể thấy khác. Sẽ làm trong các bài viết trong tương lai, thx.
Chris

@Chris Bản chỉnh sửa giúp ích rất nhiều. Cảm ơn! Và cảm ơn từ future-me khi tôi quên điều này và phải tra cứu lại!
Mnebuerquo

22

Tôi sẽ sử dụng collection.save(the_changed_dict)cách này. Tôi vừa mới thử nghiệm điều này và nó vẫn hoạt động với tôi. Sau đây là trích dẫn trực tiếp từ pymongo doc.:

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

Lưu một tài liệu trong bộ sưu tập này.

Nếu to_save đã có "_id" thì thao tác cập nhật () (upert) sẽ được thực hiện và mọi tài liệu hiện có có "_id" đó sẽ bị ghi đè. Nếu không thì thao tác insert () được thực hiện. Trong trường hợp này nếu thao tác là True, một "_id" sẽ được thêm vào to_save và phương thức này trả về "_id" của tài liệu đã lưu. Nếu thao tác là Sai, "_id" sẽ được máy chủ thêm vào nhưng phương thức này sẽ trả về Không có.


9

Đây là một câu hỏi cũ, nhưng tôi đã vấp phải điều này khi tìm câu trả lời nên tôi muốn đưa ra bản cập nhật câu trả lời để tham khảo.

Các phương pháp saveupdatekhông được dùng nữa.

save (to_save, Thao tác = True, check_keys = True, ** kwargs) ¶ Lưu tài liệu trong bộ sưu tập này.

DEPRECATED - Sử dụng insert_one () hoặc Replace_one () để thay thế.

Đã thay đổi trong phiên bản 3.0: Đã xóa tham số an toàn. Vượt qua w = 0 cho các hoạt động ghi chưa được xác nhận.

update (spec, document, upsert = False, Thao tác = False, multi = False, check_keys = True, ** kwargs) Cập nhật (các) tài liệu trong bộ sưu tập này.

DEPRECATED - Sử dụng Replace_one (), update_one () hoặc update_many () để thay thế.

Đã thay đổi trong phiên bản 3.0: Đã xóa tham số an toàn. Vượt qua w = 0 cho các hoạt động ghi chưa được xác nhận.

trong trường hợp cụ thể OPs, tốt hơn nên sử dụng replace_one.


9

Theo tài liệu mới nhất về PyMongo có tiêu đề Chèn tài liệu (chèn không được chấp nhận) và theo cách tiếp cận phòng thủ, bạn nên chèn và cập nhật như sau:

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

if post is not None:
    post['newfield'] = "abc"
    mycollection.save(post)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.