DataWeave groupBy с maxBy

Я немного новичок в DataWeave. Я пытаюсь получить последние записи о выводах для пользователя, а также сгруппировать их по типу в массиве. Это данные, с которыми мне нужно работать:

"users": [
    {
        "employeeId": "123456",
        "lastName": "smith",
        "firstName": "joe ",
        "deductions": [
            {
                "deductionType": "ABC",
                "Amt": 1000,
                "StartDate": "2001-01-02T00:00:00"
            },
            {
                "deductionType": "ABC",
                "Amt": 1000,
                "StartDate": "2019-01-02T00:00:00"
            },
            {
                "deductionType": "ABC",
                "Amt": 1000,
                "StartDate": "2016-01-02T00:00:00"
            },
            {
                "deductionType": "DCA",
                "Amt": 4000,
                "StartDate": "2019-11-02T00:00:00",
            }
        ]
    }

Я попытался использовать аналогичное решение, размещенное на странице: Dataweave 2.0 maxBy и фильтр Но это, похоже, не работает, поскольку я получаю нулевую полезную нагрузку.

Конечный результат должен выглядеть так:

    "users": [
    {
        "employeeId": "123456",
        "lastName": "smith",
        "firstName": "joe ",
        "deductions": [
            {
                "deductionType": "ABC",
                "Amt": 1000,
                "StartDate": "2019-01-02T00:00:00"
            },
            {
                "deductionType": "DCA",
                "Amt": 4000,
                "StartDate": "2019-11-02T00:00:00",
            }
        ]

Моя текущая попытка решения:

    payload.users map {($),
               deductions: (($.deductions groupBy $.deductionType) mapObject (value, key) -> 
                            {(key) : (value maxBy $.benefitStartDate)}) pluck (value) -> value

}

Но это тоже не работает.


person Tek_Datt    schedule 05.12.2019    source источник
comment
Я пытаюсь понять, каковы критерии удаления вычетов - кажется, вы просто сохраняете последний (по дате); я прав?   -  person George    schedule 05.12.2019
comment
Я пытаюсь получить записи о пользователях и вычетах для этого пользователя, сгруппированные по deductionType с последней датой начала   -  person Tek_Datt    schedule 05.12.2019


Ответы (2)


Попробуй это

{ 
    users: payload.users map {
        ($ - "deductions"),
        deductions: (($.deductions groupBy $.deductionType) pluck $) map {
            ($ maxBy $.StartDate)
        }
    }
}
person short stack stevens    schedule 05.12.2019
comment
Это приближает меня немного ближе. Теперь я просто получаю нулевого пользователя, а не полностью нулевую полезную нагрузку. - person Tek_Datt; 05.12.2019
comment
Используя ваш образец ввода, я могу получить ожидаемый конечный результат с помощью вышеуказанного преобразования. Можете ли вы опубликовать результат, который вы сейчас получаете? - person short stack stevens; 05.12.2019
comment
Я получаю только: output application / java --- {users: null} Когда я выполняю отладку. - person Tek_Datt; 06.12.2019
comment
Я также попробовал решение @shortstackstevens, и оно работает. - person George; 06.12.2019

Вот другой подход к решению, используйте тот, который работает лучше :). Комментарии к алгоритму можно увидеть в выражении DW. Более того, я жестко закодирую ваши образцы данных в коде, поэтому вам нужно только скопировать и вставить, чтобы убедиться, что выражение DW работает.

%dw 2.0
output application/dw

var data = "users": [
    {
        "employeeId": "123456",
        "lastName": "smith",
        "firstName": "joe ",
        "deductions": [
            {
                "deductionType": "ABC",
                "Amt": 1000,
                "StartDate": "2001-01-02T00:00:00"
            },
            {
                "deductionType": "ABC",
                "Amt": 1000,
                "StartDate": "2019-01-02T00:00:00"
            },
            {
                "deductionType": "ABC",
                "Amt": 1000,
                "StartDate": "2016-01-02T00:00:00"
            },
            {
                "deductionType": "DCA",
                "Amt": 4000,
                "StartDate": "2019-11-02T00:00:00",
            }
        ]
    }
]
---
users: data.users map do {
    // Sort by StartDate, I type casted to a `DateTime` instead of comparing strings
    // Reverse the sorted list such that the latest dates are at the top of the list
    // Finally, get a set out the list where uniqueness is the deductionType
    //   since distinctBy maintains the first element that matches and removes the rest
    //   you know have a list of distinct deductionType with the latest date.       
    var ds = ($.deductions orderBy ($.StartDate as DateTime))[-1 to 0]
              distinctBy (d) -> d.deductionType
    ---
    {
        ($ - "deductions"),
        deductions: ds
    }
}
person George    schedule 06.12.2019
comment
ответ выглядит интересно, объявляя var внутри основного тела dataweave --- и снова используя --- несколько раз. Могу ли я увидеть документы mule, относящиеся к этому примеру. Я в восторге от этого, спасибо - person star; 11.02.2020
comment
В DW 2.0 @star есть новый способ создания локализованных объявлений с ограниченной областью действия (также известный как замыкания). Его do {<declarations> --- <expression> }. Страница, на которой следует объяснить эту функцию, находится на этой странице: docs.mulesoft .com / mule-runtime / 4.2 /. К сожалению, это не объясняется, вместо этого у нас есть только способ using () (), который (1) является устаревшим, (2) не должен использоваться, и (3) не работает, потому что он не ограничивает объем объявлений. - person George; 11.02.2020