使用MongoEngine考虑以下内容:
class Files(Document):
name = StringField()
access_time = DateTimeField()
size = IntField()
class Folders(Document):
name = StringField()
files = ListField(field=ReferenceField('Files'))
如果我希望将文件放在按某个属性(name / access_time / size)过滤的文件夹中,有什么好办法?
我可以遍历列表(可能使用no_cache()),但是如果对象更多,则需要花费很多时间。
如何优雅地过滤在MongoEngine中具有引用的ListField?
答案 0 :(得分:0)
文档引用仅存储为mongodb中的ObjectID列表,因此您需要使用mongoengine取消引用它们以进行任何类型的过滤。
您有三种方法可以解决这个问题:
将参考存储在Files对象:
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)
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获得,并且不适用于分片集合。