更新嵌入式Mongo文档 - Mongoengine

时间:2015-09-23 06:32:57

标签: python mongodb mongodb-query mongoengine

我是一个模特 -

class Comment(EmbeddedDocument):
    c_id = Integer()
    content = StringField()

class Page(DynamicDocument):
    comments = ListField(EmbeddedDocumentField(Comment))

我插入以下数据

comment1 = Comment(c_id=1,content='Good work!')
comment2 = Comment(c_id=2,content='Nice article!')
page = Page(comments=[comment1, comment2])

现在,我想将ID为1的评论更新为Great work!。我该怎么办?

我在一些SO线程上读到它可以通过以下方式完成: -

p_obj = Page.objects.get(comments__c_id=1).update(set__comments__S__content='Great work')

但是,上述更新会引发错误说: -

Update failed (Cannot apply the positional operator without a corresponding query field containing an array.)

以下是文档结构: -

{
    "comments": [{
        "content": "Good Work",
        "c_id": "1"
    }, 
    {
        "content": "Nice article",
        "c_id": "2"
    }],
}

1 个答案:

答案 0 :(得分:0)

您需要稍微修改Comment模型。 c_id模型中的Comment字段应该是mongoengine IntField(),而不是您正在使用的Integer()

class Comment(EmbeddedDocument):
    c_id = IntField() # use IntField here
    content = StringField()

class Page(DynamicDocument):
    comments = ListField(EmbeddedDocumentField(Comment))

其次,在使用.update()执行set操作时,您需要使用.filter()代替您使用的.get(),因为.update()会尝试更新文件。

更新嵌入式文档:

我们将尝试更新Python shell中的嵌入式文档。我们将首先导入模型,然后创建2个评论实例comment1comment2。然后我们创建一个Product实例并将这些注释实例附加到它。

要执行更新,我们首先会在Product嵌入文档中过滤c_id 1comments的{​​{1}}个对象。获得过滤后的结果后,我们会使用update()在其上调用set__

例如:

In [1]: from my_app.models import Product, Comment # import models

In [2]: comment1 = Comment(c_id=1,content='Good work!') # create 1st comment instance

In [3]: comment2 = Comment(c_id=2,content='Nice article!') # create 2nd comment instance

In [4]: page = Page(comments=[comment1, comment2]) # attach coments to `Page` instance

In [5]: page.save() # save the page object
Out[5]: <Page: Page object>

# perform update operation 
In [6]: Page.objects.filter(comments__c_id=1).update(set__comments__S__content='Great work') 
Out[6]: 1 # Returns the no. of entries updated

检查值是否已更新:

我们可以通过进入mongo shell并在.find()上执行page_collection来检查该值是否已更新。

> db.page_collection.find()
{ "_id" : ObjectId("5605aad6e8e4351af1191d3f"), "comments" : [ { "c_id" : 1, "content" : "Great work" }, { "c_id" : 2, "content" : "Nice article!" } ] }