Nej med listefelt kan du ikke lave en upsert til en liste i en enkelt forespørgsel. $addToSet
virker ikke, da du har ændret post
så du kan ikke matche. Du kan kode rundt om dette, men det skaber en løbstilstand, hvor der er en lille mulighed for fejl, f.eks.:
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 forsøger vi at opdatere, og hvis det ikke eksisterer, skubber vi til listen - det er her, der er et vindue af muligheder for en anden proces at køre og potentielt skubbe post
på listen.
Risikoen kan være acceptabel, men realistisk tror jeg, at det er bedre at ændre dit skema, hvilket potentielt kan opdele Post
ud i sin egen samling. Så kan du bruge en opdateringssætning og indstille hele objektet. Prisen vil være en ekstra forespørgsel for at få feeddataene.