MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Aktualisieren einer Liste eingebetteter Dokumente in mongoengine

Nein, mit Listenfeld können Sie in einer einzigen Abfrage kein Upsert in eine Liste durchführen. $addToSet funktioniert nicht, da du den post geändert hast Sie können also nicht übereinstimmen. Sie können dies runden, aber es erzeugt eine Race-Bedingung, bei der es ein kleines Zeitfenster für Fehler gibt, z. B.:

    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)

Zuerst versuchen wir zu aktualisieren, und wenn es nicht existiert, verschieben wir es auf die Liste – hier gibt es ein Zeitfenster, in dem ein anderer Prozess ausgeführt und möglicherweise den post übertragen kann auf der Liste.

Das Risiko mag akzeptabel sein, aber realistisch gesehen denke ich, dass es besser ist, Ihr Schema zu ändern und möglicherweise Post aufzuteilen in eine eigene Sammlung. Dann können Sie eine Update-Anweisung verwenden und das gesamte Objekt festlegen. Die Kosten sind eine zusätzliche Abfrage zum Abrufen der Feed-Daten.