Nej med listfält kan du inte göra en upsert till en lista i en enda fråga. $addToSet
fungerar inte eftersom du har ändrat post
så du kan inte matcha. Du kan koda runt detta men det skapar ett tävlingstillstånd där det finns ett litet fönster av möjlighet till fel, t.ex.:
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)
Först försöker vi att uppdatera och om det inte finns trycker vi till listan - det är här det finns en möjlighet för en annan process att köra och eventuellt trycka post
på listan.
Risken kan vara acceptabel men realistiskt sett tror jag att det är bättre att ändra ditt schema, eventuellt dela upp Post
ut i sin egen samling. Sedan kan du använda en uppdateringssats och ställa in hela objektet. Kostnaden kommer att vara en extra fråga för att få flödesdata.