Mongo Aggregation - Използване на променливи, създадени в $project

Възможно ли е да се използват променливи, дефинирани във фазата $project в същата тази фаза? Например, имам този тръбопровод за агрегиране:

    pipeline = [{   
        '$match': {}
    },
    {
        '$group': {
            '_id': '$_id',
            'n': {'$first': 'n'}
    },
    {
        '$project': {
            'name': 1,
            'n': 1,
            'revenue': {'$multiply': ['$n', 2]},
            'cost': {'$multiply': ['$revenue', 0.25]}
        }
    }]

Бих искал да използвам променливата $revenue (която дефинирах в $project) в същата фаза на $project, за да изчисля стойността на разходите, но това не работи.

Има ли някакъв начин да направя това лесно и ефективно? Мислех да направя няколко проекции, но ще трябва да проектирам много променливи (~25 променливи) всеки път, когато трябва да изчисля една допълнителна променлива, и имам куп променливи за изчисляване, които зависят една от друга (~5 променливи), и кодът ми вероятно ще изглежда зле, тъй като ще има много проектиране на едни и същи променливи. Как трябва да се справя с това?


person Marc    schedule 17.12.2013    source източник


Отговори (2)


Не, но можете да вложите оператори на проекция като заобиколно решение:

pipeline = [{   
    '$match': {}
},
{
    '$group': {
        '_id': '$_id',
        'n': {'$first': 'n'}
},
{
    '$project': {
        'name': 1,
        'n': 1,
        'revenue': {'$multiply': ['$n', 2]},
        'cost': {'$multiply': [{'$multiply': ['$n', 2]}, 0.25]}
    }
}]

Което в този случай можете да опростите до:

pipeline = [{   
    '$match': {}
},
{
    '$group': {
        '_id': '$_id',
        'n': {'$first': 'n'}
},
{
    '$project': {
        'name': 1,
        'n': 1,
        'revenue': {'$multiply': ['$n', 2]},
        'cost': {'$multiply': ['$n', 2, 0.25]}
    }
}]
person JohnnyHK    schedule 17.12.2013
comment
Добре, но всяка променлива е няколко реда код и бих имал много вложени променливи във всяко изчисление. Ще трябва да влагам изчислението на променливата всеки път, когато трябва да я използвам, което няма да има смисъл, ако имам 5 променливи, зависещи една от друга, където трябва да използвам всяка променлива около 5 пъти при всяко изчисление. Но благодаря за предложението! - person Marc; 17.12.2013

Току-що попаднах тук, докато търсех същия проблем. Моето текущо решение е добавяне на повече $project етапи и винаги вземане на всички други полета. За вашия пример ще изглежда така:

pipeline = [{   
    '$match': {}
},
{
    '$group': {
        '_id': '$_id',
        'n': {'$first': 'n'}
},
{
    '$project': {
        'name': 1,
        'n': 1,
        'revenue': {'$multiply': ['$n', 2]}
    }
},
{
    '$project': {
        'name': 1,
        'n': 1,
        'revenue': 1,
        'cost': {'$multiply': ['$revenue', 0.25]}
    }
}]

Все още не намерих по-добро решение, ако искате да запазите всички предишни изчислени полета, без да използвате повторно изрази няколко пъти.

person Maik Laschober    schedule 09.06.2021