更新嵌入式 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 个评论实例 comment1
和 comment2
。然后我们创建一个 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!" } ] }
我有一个模型 -
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 个评论实例 comment1
和 comment2
。然后我们创建一个 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!" } ] }