2013-02-04 53 views
4

我想从ListField(ReferenceField)中删除一些参考,仅基于它们的值。MongoEngine - 从ListField中提取参考,编号

我存储有关的下列型号的图像信息:

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

我们存储id个页面上遇到的图像在EmbeddedDocument称为Webpage

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

最后,Website型号被嵌入到RawData型号中:

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

我想从RawData记录中删除对它们的某些属性(例如:计数器值超过1)的引用,然后将这些ImageUrl记录的deleted属性设置为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?,我需要指定我想从中删除值的数组的关键。但是,就我而言,我想从列表中删除一个值...我应该怎么做?

非常感谢您的时间!

回答

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无需refind该文件!

OperationError: Update failed [Cannot apply $pull/$pullAll modifier to non-array]这意味着您正在尝试拉取需要数组的数据,并且存在一个文档,其中image_list实际上不是数组。这可能是因为磁盘上有一个文档,其中image_list实际上不是一个列表。如果您尝试使用除块以外的其他功能,则可以查看文档,看看是否属实,如果是这样,则需要手动迁移。

+0

再次罗斯,非常感谢你! –