2016-02-09 39 views
0

考慮使用MongoEngine如下:Mongoengine ORM過濾

class Files(Document): 
    name = StringField() 
    access_time = DateTimeField() 
    size = IntField() 

class Folders(Document): 
    name = StringField() 
    files = ListField(field=ReferenceField('Files')) 

如果我希望通過一些屬性(名稱/ access_time /大小)過濾的文件夾中獲取文件夾,有什麼好辦法?

我可以遍歷列表(也許通過使用no_cache()),但如果對象更多,這將花費很多時間。

如何優雅地過濾在MongoEngine中有引用的ListField?

+0

您連接的是哪個版本的mongodb? –

回答

0

文檔引用僅存儲在mongodb中的ObjectID列表中,因此您需要mongoengine來取消引用它們以執行任何類型的過濾。

你有三種選擇來解決這個問題:

存儲上的文件對象的引用:

class Files(Document): 
    name = StringField() 
    access_time = DateTimeField() 
    size = IntField() 
    folder = ReferenceField(Folders) 

folder = Folders.objects.first() 
big_files = Files.objects(size__gt=500,folder=folder).all() 

存儲文件嵌入文檔:

class Files(EmbeddedDocument): 
    name = StringField() 
    access_time = DateTimeField() 
    size = IntField() 

class Folders(Document): 
    name = StringField() 
    files = EmbeddedDocumentListField(Files) 

使用aggregation framework

pipeline = [ 
    {"$unwind": "$files"}, 
    {"$lookup": 
     { 
      "from": "files", 
      "localField": "files", 
      "foreignField": "_id", 
      "as": "files" 
     }}, 
    {"$unwind": "$files"}, 
    {"$match": {"files.size": {"$gt": 500}}}, 
    {"$group": { 
     "_id": "$_id", 
     "name": {"$first": "$name"}, 
     "files": {"$push": "$files"} 
    }}, 

] 

folders = Folders.objects.aggregate(*pipeline) 

您使用的是基於您的真實應用程序,但不是聚合管道上的$lookup僅適用於mongodb版本3.2,不適用於分片集合。