4

我想从 a 中删除一些引用ListField(ReferenceField),仅基于它们的值。

我将有关图像的信息存储在以下模型中:

class ImageUrl(Document):
    src = UrlField()
    counter = IntField()
    deleted = BooleanField()

我们将id页面上遇到的图像的 s存储在EmbeddedDocument被调用的Webpage

class Webpage(EmbeddedDocument):
    image_list = ListField(ReferenceField(ImageUrl))
    ...

最后将Website模型嵌入到RawData模型中:

class RawData(Document):
    ...
    webpage = EmbeddedDocumentField(Webpage)

我想ImageUrlRawData记录中删除对记录的引用,基于它们的一些属性(例如:计数器值超过 1),然后将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操作引发以下错误: OperationError: Update failed [Cannot apply $pull/$pullAll modifier to non-array]

正如我从http://docs.mongodb.org/manual/reference/operator/pull/#_S_pullHow to remove a item from a list(ListField) by id in MongoEngine? ,我需要指定要从中删除值的数组的键。但是,就我而言,我想从列表中删除一个值......我应该怎么做?

非常感谢您的宝贵时间!

4

1 回答 1

5

位置运算符的工作方式是它允许您查询列表中的值,然后对该值的第一个实例执行操作,通常是更新。 $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实际上不是列表的文档。如果您尝试除块之外,您可以查看无法查看是否是这种情况的文档,如果是这种情况,则需要手动迁移。

于 2013-02-08T11:40:19.897 回答