Есть ли способ DRY написать оператор if / elif / else в Python, который определяет конвейер $ match, используемый в агрегации Mon go - PullRequest
0 голосов
/ 09 июля 2020

В настоящее время я повторяю агрегацию 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?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...