MongoEngine - 通过id从ListField中提取引用

时间:2013-02-04 10:22:15

标签: python mongodb mongoengine

我想从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_pullHow to remove a item from a list(ListField) by id in MongoEngine?所理解的那样,我需要指定要从中删除值的数组的键。但是,在我的情况下,我想从列表中删除一个值...我应该怎么做?

非常感谢你的时间!

1 个答案:

答案 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块,您可以查看无法查看是否是这种情况的文档,如果是,则需要手动迁移。