【问题标题】:Update Embedded Mongo Documents - Mongoengine更新嵌入式 Mongo 文档 - Mongoengine
【发布时间】:2015-09-23 06:32:56
【问题描述】:

我有一个模特 -

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"
    }],
}

【问题讨论】:

    标签: python mongodb mongodb-query mongoengine


    【解决方案1】:

    您需要稍微修改您的Comment 模型。 Comment 模型中的 c_id 字段应该是 mongoengine 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 嵌入文档中将具有c_idProduct 对象过滤为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!" } ] }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-19
    • 2012-09-05
    • 1970-01-01
    • 2015-01-12
    • 2014-05-15
    • 2013-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多