更新mongoengine中的嵌入式文档列表
问题描述:
我正在努力使用mongoengine语法。更新mongoengine中的嵌入式文档列表
我有以下型号...
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
...与传递到日志对象my_method,我想更新现有的岗位,如果它与self.posts存在匹配uid,或者如果不是,则推送到self.posts。
在mongoengine的一个调用中是否有语法来做到这一点?
答
否与列表字段不能在单个查询中进行列表中的upsert。 $addToSet
不会工作,因为你已经改变了post
,所以你不能匹配。您可以编写这一轮,但它确实创造竞争条件哪里有机会的错误如一个小窗口:
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
。
风险可能是可以接受但现实的,我认为改变你的模式更好,可能会将Post
分成它自己的集合。然后你可以使用更新语句并设置整个对象。成本将是一个额外的查询来获取供稿数据。
答
Feed.objects.filter(posts__uid=post.uid).\
update_one(push__posts__S__comments='comment demo')
完美,谢谢! –
@Ross如何得到这个响应'WriteResult({“nMatched”:0,“nUpserted”:0,“nModified”:0})'使用'mongoengine'?我想检查是否找到该项目。谢谢 –