更新嵌入式 Mongo 文档 - Mongo 引擎

Update Embedded Mongo Documents - 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"
    }],
}

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

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

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

其次,当使用 set 执行 .update() 操作时,您需要使用 .filter() 而不是您正在使用的 .get(),因为 .update() 将尝试更新文档。

正在更新嵌入文档:

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

要执行更新,我们将首先在 comments 嵌入文档中过滤 Product 个具有 c_id 作为 1 的对象。获得过滤结果后,我们将使用 set__.

在其上调用 update()

例如:

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 并在 page_collection 上执行 .find() 来检查值是否已更新。

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