我是一个模特 -
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"
}],
}
答案 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个评论实例comment1
和comment2
。然后我们创建一个Product
实例并将这些注释实例附加到它。
要执行更新,我们首先会在Product
嵌入文档中过滤c_id
1
为comments
的{{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!" } ] }