MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Atualizando uma lista de documentos incorporados no mongoengine


Não, com o campo de lista, você não pode fazer um upsert em uma lista em uma única consulta. $addToSet não funcionará porque você alterou o post então você não pode combinar. Você pode codificar em volta disso, mas cria uma condição de corrida em que há uma pequena janela de oportunidade para erro, por exemplo:
    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)

Primeiro, tentamos atualizar e, se não existir, enviamos para a lista - é aqui que há uma janela de oportunidade para que outro processo seja executado e, potencialmente, envie o post na lista.

O risco pode ser aceitável, mas, realisticamente, acho que é melhor alterar seu esquema, potencialmente dividindo Post em sua própria coleção. Então você pode usar uma instrução de atualização e definir todo o objeto. O custo será uma consulta extra para obter os dados do feed.