2013-02-04 33 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

再次羅斯,非常感謝你! –