Агрегация Mongodb: передача аргументов в пользовательскую функцию - PullRequest
0 голосов
/ 25 июня 2018

Вот мой запрос агрегации

blockColctn.aggregate([{
    "$match": {
        "number": blockNumber
    }

    },
    {
    "$project": {
        "transactions.to": "$transactions.to",
        "transaction": "$transactions",
        "transactions.hash": "$transactions.hash",


    }
    },
    {
    "$lookup": {
        "from": "token_collections",
        "localField": "transactions.to",
        "foreignField": "tokencontractaddress",
        "as": "tokenaccount"
    }
    },
    {
    "$project": {
       "total":getTotal("transactions.hash")
    }
    }])

Я звоню getTotal в $project, он работает нормально, однако я хотел бы передать значение столбца transactions.hash в качестве аргумента функции.Я обнаружил похожую проблему, связанную с моей Пользовательскими функциями, вычисляемыми столбцами проекции mongodb

Но это не говорит о передаче аргументов

1 Ответ

0 голосов
/ 26 июня 2018

Начал бы с рефакторинга вышеупомянутого, сначала создав функцию, которая принимает значение столбца total в качестве аргумента функции и возвращает массив конвейера:

const getAggregatePipeline = total => ([
    { "$match": {
        "number": blockNumber
    } },
    { "$project": {
        "transactions.to": "$transactions.to",
        "transaction": "$transactions",
        "transactions.hash": "$transactions.hash",
    } },
    { "$lookup": {
        "from": "token_collections",
        "localField": "transactions.to",
        "foreignField": "tokencontractaddress",
        "as": "tokenaccount"
    } },
    { "$project": { total } }
])

Теперь вы можете передать это вМетод агрегирования как

blockColctn.aggregate(getAggregatePipeline(getTotal("transactions.hash")))

Как вы можете видеть, мы просто вкладываем функции друг в друга, чтобы при вызове их с конечным значением результат взрывался через каждый слой.Это может быть дополнительно изменено, чтобы создать композицию всех этих функций (то есть, которая возвращает новую функцию) со следующим планом

const compose = (f1, f2, f3) => value => f1( f2( f3(value) ) )

Затем вы можете вызвать это как

const agg = compose(blockColctn.aggregate, getAggregatePipeline, getTotal)("transactions.hash")

Для составной функции, которая является полностью вариативной, то есть той, которая может принимать произвольно длинный список функций и затем работать справа налево (от внутренней к внешней):

const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args)))
...