No, con el campo de lista no puede hacer una inserción en una lista en una sola consulta. $addToSet
no funcionará ya que has cambiado la post
por lo que no puede coincidir. Puede codificar esto, pero crea una condición de carrera donde hay una pequeña ventana de oportunidad para el error, por ejemplo:
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)
Primero intentamos actualizar y, si no existe, empujamos a la lista; aquí es donde hay una ventana de oportunidad para que se ejecute otro proceso y potencialmente empujar la post
en la lista.
El riesgo puede ser aceptable pero, de manera realista, creo que cambiar su esquema es mejor, potencialmente dividiendo Post
en su propia colección. Luego puede usar una declaración de actualización y configurar todo el objeto. El costo será una consulta adicional para obtener los datos del feed.