Сложный запрос MongoDB с использованием 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')

Мне нужно сделать запрос, который будет возвращать ответ в следующей форме:

[{
   "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>"
                    }]
                }]
             }]
}]

Можно ли получить такой ответ только одним запросом?

1 ответ

Решение

Это правильный запрос, чтобы получить ответ вроде этого:

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]
Другие вопросы по тегам