我想从ListField(ReferenceField)
中移除一些引用,仅基于它们的值。
我在以下模型中存储有关图像的信息:
class ImageUrl(Document):
src = UrlField()
counter = IntField()
deleted = BooleanField()
我们将页面上遇到的图片的id
存储在名为EmbeddedDocument
的{{1}}中:
Webpage
最后,class Webpage(EmbeddedDocument):
image_list = ListField(ReferenceField(ImageUrl))
...
模型嵌入到Website
模型中:
RawData
我想基于某些属性(例如:计数器值超过1)从class RawData(Document):
...
webpage = EmbeddedDocumentField(Webpage)
记录中删除对ImageUrl
条记录的引用,然后设置RawData
属性这些deleted
记录到ImageUrl
。
我在做:
True
images = ImageUrl.objects((Q(deleted=False) & Q(counter__gt=1)).all()
for image in images:
# all RadData records containing the image in their image list
for rdata in RawData.objects(webpage__image_list__in=[image.id]:
# remove image from the image_list
RawData.objects(id=rdata.id).update_one(pull__webpage__image_list=image.id)
# set 'deleted=True' on the ImageUrl record
ImageUrl.objects(id=image.id).update_one(set__deleted=True)
操作引发以下错误:
pull
。
正如我从http://docs.mongodb.org/manual/reference/operator/pull/#_S_pull或How to remove a item from a list(ListField) by id in MongoEngine?所理解的那样,我需要指定要从中删除值的数组的键。但是,在我的情况下,我想从列表中删除一个值...我应该怎么做?
非常感谢你的时间!
答案 0 :(得分:3)
位置运算符的工作方式是它允许您查询列表中的值,然后对该值的第一个实例执行操作,通常是更新。 $pull
将从列表中删除所有实例,这就是您想要的。
在带有引用的mongoengine中,您只需传递实例对象,例如:
for rdata in RawData.objects(webpage__image_list=image):
# remove image from the image_list
rdata.update_one(pull__webpage__image_list=image)
我清理了代码,删除了重复的查询 - 因为您已经rdata
无需重新标记该文档!
OperationError: Update failed [Cannot apply $pull/$pullAll modifier to non-array]
这意味着您正在尝试提取需要数组的数据,并且文档中image_list
实际上不是数组。这可能是因为在磁盘上有一个image_list
实际上不是列表的文档。如果您放置一个try except块,您可以查看无法查看是否是这种情况的文档,如果是,则需要手动迁移。