Сложный запрос 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]