Ne s polem seznamu nemůžete provést upsert do seznamu v jediném dotazu. $addToSet
nebude fungovat, protože jste změnili post
takže se nemůžete shodovat. Můžete to zakódovat, ale vytvoří to konfliktní podmínku, kde existuje malé okno příležitosti pro chybu, např.:
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)
Nejprve se pokusíme aktualizovat a pokud neexistuje, zatlačíme do seznamu – zde je příležitost ke spuštění dalšího procesu a potenciálně vložení post
na seznamu.
Riziko může být přijatelné, ale realisticky si myslím, že změna schématu je lepší, případně rozdělení Post
do vlastní sbírky. Pak můžete použít příkaz update a nastavit celý objekt. Cena bude další dotaz na získání dat zdroje.