2016-02-09 42 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,不适用于分片集合。