Không với trường danh sách, bạn không thể thực hiện nâng cấp vào danh sách trong một truy vấn duy nhất. $addToSet
sẽ không hoạt động vì bạn đã thay đổi post
vì vậy bạn không thể phù hợp. Bạn có thể viết mã vòng này nhưng nó tạo ra một điều kiện chạy đua trong đó có một cơ hội nhỏ cho lỗi, ví dụ:
class Post(EmbeddedDocument):
uid = StringField(required=True)
text = StringField(required=True)
class Feed(Document):
label = StringField(required=True)
feed_url = StringField(required=True)
posts = ListField(EmbeddedDocumentField(Post))
Feed.drop_collection()
Feed(
label="label",
feed_url="www.feed.com"
).save()
post = Post(uid='1', text="hi")
updated = Feed.objects(posts__uid=post.uid).update_one(set__posts__S=post)
if not updated:
Feed.objects.update_one(push__posts=post)
Trước tiên, chúng tôi cố gắng cập nhật và nếu nó không tồn tại, chúng tôi đẩy vào danh sách - đây là nơi có cơ hội cho một quy trình khác chạy và có khả năng đẩy post
trong danh sách.
Rủi ro có thể chấp nhận được nhưng trên thực tế, tôi nghĩ rằng việc thay đổi lược đồ của bạn sẽ tốt hơn, có khả năng tách Post
ra vào bộ sưu tập của riêng mình. Sau đó, bạn có thể sử dụng một câu lệnh cập nhật và thiết lập toàn bộ đối tượng. Chi phí sẽ là một truy vấn bổ sung để lấy dữ liệu nguồn cấp dữ liệu.