MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Aggiornamento di un elenco di documenti incorporati in mongoengine

No, con il campo elenco non è possibile eseguire un upsert in un elenco in una singola query. $addToSet non funzionerà perché hai cambiato il post quindi non puoi eguagliare. Puoi codificare attorno a questo, ma crea una condizione di gara in cui c'è una piccola finestra di opportunità per l'errore, ad esempio:

    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)

Per prima cosa proviamo ad aggiornare e, se non esiste, inseriamo l'elenco:è qui che c'è una finestra di opportunità per un altro processo da eseguire e potenzialmente inviare il post nell'elenco.

Il rischio potrebbe essere accettabile ma realisticamente, penso che cambiare lo schema sia meglio, potenzialmente dividere Post fuori nella propria collezione. Quindi puoi utilizzare un'istruzione di aggiornamento e impostare l'intero oggetto. Il costo sarà una query aggiuntiva per ottenere i dati del feed.