更新mongoengine中的嵌入式文档列表 [英] Updating a list of embedded documents in mongoengine

查看:153
本文介绍了更新mongoengine中的嵌入式文档列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力使用mongoengine语法.

I'm struggling with mongoengine syntax.

我有以下型号...

class Post(EmbeddedDocument):
    uid = StringField(required=True)
    text = StringField(required=True)
    when = DateTimeField(required=True)


class Feed(Document):
    label = StringField(required=True)
    feed_url = StringField(required=True)
    posts = ListField(EmbeddedDocumentField(Post))

    def my_method(self, post):
        pass

...,并将post对象传递到my_method中,如果它存在于self.posts中,并且具有匹配的uid,那么我想更新现有的post,如果不存在,则推送到self.posts.

... and with the post object passed into to my_method, I'd like to update an existing post if it exists in self.posts with a matching uid, or push to self.posts if not.

在mongoengine中的一次调用中是否有语法可以做到这一点?

Is there syntax to do that in one call in mongoengine?

推荐答案

否,对于列表字段,您无法在单个查询中对列表进行向上更新. $addToSet无效,因为您已更改post,因此无法进行匹配.您可以对此进行编码,但是它确实会创建一个竞争条件,在该竞争条件中,机会很小的错误例如:

No with list field you cannot do an upsert into a list in a single query. $addToSet wont work as you've changed the post so you cant match. You can code round this but it does create a race condition where there is a small window of opportunity for error eg:

    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)

首先,我们尝试更新,如果不存在,我们将推送至列表-这是运行其他进程并有可能将post推送至列表的机会之窗.

First we try to update and if it doesn't exist we push to the list - this is where there is a window of opportunity for another process to run and potentially push the post on the list.

风险可能是可以接受的,但实际上,我认为更改架构会更好,有可能将Post拆分为自己的集合.然后,您可以使用一条update语句并设置整个对象.这将是获取提要数据的额外查询.

The risk might be acceptable but realistically, I think changing your schema is better, potentially splitting Post out into its own collection. Then you can use an update statement and set the whole object. The cost will be an extra query to get the feed data.

这篇关于更新mongoengine中的嵌入式文档列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆