В настоящее время я повторяю агрегацию Mon go 4 раза, по одному для каждого результата в операторе if> if / elif / else / else. Единственное, что изменяется в каждом конвейере агрегации, - это условие $ match.
Мой код выглядит так:
if condition:
condition_a = []
condition_b = []
# form data populates condition_a and condition_b as [{"string": "data"}, {"string": "data"}, etc..]
if len(condition_b) == 0:
query = coll.aggregate(
[
{"$unwind": "$file"},
{"$match": {"id_file": value, "$or": condition_a}},
{
"$lookup": {
"from": "...", etc...
}
},
{"$unwind": "$..."},
{"$project": { etc.. } },
]
)
elif len(condition_a) == 0:
query = coll.aggregate(
[
{"$unwind": "$file"},
{"$match": {"id_file": value, "$or": condition_b}},
{
"$lookup": {
"from": "...", etc...
}
},
{"$unwind": "$..."},
{"$project": { etc.. } },
]
)
else:
query = coll.aggregate(
[
{"$unwind": "$file"},
{"$match": {"id_file": value,
"$and": [{"$or": condition_a}, {"$or": condition_b}]
}},
{
"$lookup": {
"from": "...", etc..
}
},
{"$unwind": "$..."},
{"$project": { etc.. } },
]
)
else:
query = coll.aggregate(
[
{"$unwind": "$file"},
{"$match": {"id_file": value}},
{"$lookup": {
"from": "...", etc..
}
},
{"$unwind": "$..."},
{"$project": { etc.. } },
]
)
Это явно не идеально! Я надеялся, что смогу написать агрегирование только один раз, используя переменную для представления условия. Значение переменной будет определяться оператором if / elif / else.
Но я понимаю, что у меня не может быть переменной с элементами строкового типа и типа списка, как в моей попытке ниже !!:
if len(condition_b) == 0:
condition = "'$or': '" + condition_a + "'"
elif len(condition_a) == 0:
condition = "'$or': '" + condition_b + "'"
else:
condition = "'$and': [{'$or': '" + condition_a + "'}, [{'$or': '" + condition_b + "'},"
else:
condition = ""
Где будет находиться конвейер $ match: {"$match": {"id_file": value, condition }}
Могу ли я что-нибудь сделать здесь, чтобы сделать его больше DRY?