使用 MongoEngine 的复杂 MongoDB 查询

Complex MongoDB query using MongoEngine

伙计们!

我正在尝试 MongoDB(版本 3.2)和 MongoEngine 并想进行复杂的查询,但我完全不知道如何做到这一点。如果可能的话。

有 4 个文档:

class File(EmbeddedDocument):
    path = StringField()

class Episode(EmbeddedDocument):
    num = IntField()
    alias = StringField()
    files = EmbeddedDocumentListField('File')

class Season(Document):
    num = IntField()
    alias = StringField()
    episodes = EmbeddedDocumentListField('Episode', db_field='items')

class Series(Document):
    title = StringField()
    alias = StringField()
    description = StringField()
    seasons = ListField(ReferenceField('Season'), db_field='items')

我需要查询 return 以下形式的响应:

[{
   "path": "/series/<series alias>",
   "title": "<series title>",
   "description": "<series description>",
   "seasons": [{
                "path": "/series/<aseries alias>/<season alias>",
                "title": "Season <season num>",
                "episodes": [{
                    "path": "/series/<series alias>/<season alias>/<episode alias>",
                    "title": "Episode <episode num>",
                    "files": [{
                        "path": "<path>"
                    }]
                }]
             }]
}]

是否可以仅通过一次查询就收到这样的响应?

这是获得如下响应的正确查询:

cursor = Series.objects.all().aggregate(
        {'$unwind': '$items'},
        {'$lookup': {
            'from': 'products',
            'localField': 'items',
            'foreignField': '_id',
            'as': 'seasons'
        }},
        {'$project': {
            'path': {'$concat': ['/series/', '$alias']},
            'title': '$title',
            'description': '$description',
            'seasons': {
                '$map': {
                    'input': '$seasons',
                    'as': 'season',
                    'in': {
                        'path': {'$concat': ['/series/', '$alias', '/', '$$season.alias']},
                        'title': {'$concat': ['Season ', {'$substr': ['$$season.num', 0, -1]}]},
                        'episodes': {
                            '$map': {
                                'input': '$$season.items',
                                'as': 'episode',
                                'in': {
                                    'path': {'$concat': ['/series/', '$alias', '/', '$$season.alias', '/', '$$episode.alias']},
                                    'title': {'$concat': ['Episode ', {'$substr': ['$$episode.num', 0, -1]}]},
                                    'files': {
                                        '$map': {
                                            'input': '$$episode.files',
                                            'as': 'files',
                                            'in': {
                                                'path': '$$files.path'
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }})
res = list(cursor)[0]