Dataweave - Как преобразовать массив элементов в родительско-дочернее отношение в Dataweave

Я хочу преобразовать приведенный ниже ввод в вывод JSON родитель-потомок, используя преобразование dataweave. Пожалуйста, дайте мне знать, если кто-нибудь работал над этим раньше. Я добавил пример ввода и вывода json ниже.

Обновленный пост с дополнительными узлами: мне нужно несколько родительских узлов с уровнем местоположения = 1 с соответствующими иерархиями.

Введите JSON-формат:

[
    {
        "ENTITY_ID": 1,
        "PARENT_EID": 1,
        "LOCATION_LEVEL": 1,
        "LOCATION_CODE": "123"
    },
    {
        "ENTITY_ID": 2,
        "PARENT_EID": 1,
        "LOCATION_LEVEL": 2,
        "LOCATION_CODE": "234"
    },
    {
        "ENTITY_ID": 3,
        "PARENT_EID": 2,
        "LOCATION_LEVEL": 3,
        "LOCATION_CODE": "345"
    },
    {
        "ENTITY_ID": 4,
        "PARENT_EID": 1,
        "LOCATION_LEVEL": 2,
        "LOCATION_CODE": "567"
    },
    {
        "ENTITY_ID": 5,
        "PARENT_EID": 5,
        "LOCATION_LEVEL": 1,
        "LOCATION_CODE": "012"
    },
    {
        "ENTITY_ID": 6,
        "PARENT_EID": 5,
        "LOCATION_LEVEL": 1,
        "LOCATION_CODE": "023"
    }
]

Формат вывода json:

[
    {
        "ENTITY_ID": 1,
        "PARENT_EID": 1,
        "LOCATION_LEVEL": 1,
        "LOCATION_CODE": "123",
        "CHILDRENS":[
                {
                    "ENTITY_ID": 2,
                    "PARENT_EID": 1,
                    "LOCATION_LEVEL": 2,
                    "LOCATION_CODE": "234"
                    "CHILDRENS":[{
                            "ENTITY_ID": 3,
                            "PARENT_EID": 2,
                            "LOCATION_LEVEL": 3,
                            "LOCATION_CODE": "345"                          
                    }]
                },
                {
                    "ENTITY_ID": 4,
                    "PARENT_EID": 1,
                    "LOCATION_LEVEL": 2,
                    "LOCATION_CODE": "567"
                }
        ]
        
    },
    {
        "ENTITY_ID": 5,
        "PARENT_EID": 5,
        "LOCATION_LEVEL": 1,
        "LOCATION_CODE": "012",
        "CHILDRENS":[{
                  "ENTITY_ID": 6,
                  "PARENT_EID": 5,
                  "LOCATION_LEVEL": 2,
                  "LOCATION_CODE": "023"
              }]
    }
]
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
427
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Попробуйте это:

%dw 2.0
output application/json

var data = [
    {
        "ENTITY_ID": 1,
        "PARENT_EID": 1,
        "LOCATION_LEVEL": 1,
        "LOCATION_CODE": "123"
    },
    {
        "ENTITY_ID": 2,
        "PARENT_EID": 1,
        "LOCATION_LEVEL": 2,
        "LOCATION_CODE": "234"
    },
    {
        "ENTITY_ID": 3,
        "PARENT_EID": 2,
        "LOCATION_LEVEL": 3,
        "LOCATION_CODE": "345"
    },
    {
        "ENTITY_ID": 4,
        "PARENT_EID": 1,
        "LOCATION_LEVEL": 2,
        "LOCATION_CODE": "567"
    },
    {
        "ENTITY_ID": 5,
        "PARENT_EID": 5,
        "LOCATION_LEVEL": 1,
        "LOCATION_CODE": "012"
    },
    {
        "ENTITY_ID": 6,
        "PARENT_EID": 5,
        "LOCATION_LEVEL": 2,
        "LOCATION_CODE": "023"
    }
]

var top = data filter ($.LOCATION_LEVEL == 1)

fun insert(t,e) = t match {
    case {} -> e
    case tree if (tree.ENTITY_ID == e.PARENT_EID) -> do {
        var node = tree - "CHILDREN"
        var children = if (tree.CHILDREN?) (tree.CHILDREN + e) else [e]
        ---
        {(node),CHILDREN: children}
    }
    case tree if (tree.ENTITY_ID != e.PARENT_EID) -> do {
        var node = tree - "CHILDREN"
        var children = tree.CHILDREN map ($ insert e)
        ---
        {(node), (CHILDREN: children) if (not isEmpty(children))}
    }
    else -> $
}


---
top map (topnode) -> (
    (data -- top) orderBy $.ENTITY_ID reduce ((e, acc=topnode) -> acc insert e)
) 

Протестируйте его с большим количеством входных данных, и вам может потребоваться скорректировать код, если некоторые другие тестовые примеры не пройдут.

Вы (или, может быть, кто-то другой) можете переписать это, используя оператор update, по сравнению с созданием переменных node и children, как это делаю я.

Работает до 8 уровня дочерних узлов. однако, когда я пытаюсь вставить дочерний узел для 4-го родителя, это не удается. Спасибо за ответ, это много значит

Sandesh patil 28.12.2020 15:14

Изолируйте запись, которая вызывает проблему, затем проверьте ее и воспроизведите поведение в своих образцах данных. Также будет полезно, если вы предоставите сообщение об ошибке, которое вы получите.

George 30.12.2020 04:38

В случае повторного запуска с location_level 1 означает новую иерархию, такой тип senario не работает, как новый уровень Location 1.

Sandesh patil 31.12.2020 14:45

Что делать, если у меня есть другой узел с местоположением 1, как показано ниже { "ENTITY_ID": 2, "PARENT_EID": 2, "LOCATION_LEVEL": 1, "LOCATION_CODE": "156" }

Sandesh patil 02.01.2021 14:59

Итак, мы не будем ходить туда-сюда, вам нужно предоставить образцы данных, которые фиксируют все перестановки. Затем вам нужно изменить свой исходный пост, чтобы он содержал образцы данных. Кроме того, вы ДОЛЖНЫ предоставить алгоритмические детали (т. е. логику) того, как вы связываете родительские и дочерние узлы. Тогда и только тогда я смогу помочь дальше.

George 02.01.2021 17:19

Только что обновил мой вопрос дополнительными узлами. Спасибо за ваш ответ

Sandesh patil 06.01.2021 12:48

Обратите внимание, используя ваше выражение dataweave, я не получаю массив иерархических данных, как в скобках [ ]. Это в скобках {}. Еще раз спасибо :)

Sandesh patil 06.01.2021 12:51

Также обратите внимание, что это пример данных. В реальных данных есть около 5000 списков узлов, которые я преобразовываю. Я получаю сообщение об ошибке Java.lang.stackoverflow. Есть ли способ оптимизировать это?

Sandesh patil 06.01.2021 12:55

Что касается логики, то она основана исключительно на отношении родительского идентификатора eid и идентификатора сущности, а также на уровне местоположения. Если уровень местоположения = 1, то его родительский узел

Sandesh patil 06.01.2021 12:57

Ты здесь, Джордж?

Sandesh patil 08.01.2021 12:09

Да, я Сандеш, но я занят на этой неделе — возможно, я посмотрю на него в выходные.

George 08.01.2021 13:59

Пожалуйста, перепроверьте свои образцы данных - кажется, что последняя запись должна иметь LOCATION_LEVEL: 2

George 09.01.2021 15:42

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

George 09.01.2021 16:23
%dw 2.0
output application/json
var Input = [
    {
        "ENTITY_ID": 1,
        "PARENT_EID": 1,
        "LOCATION_LEVEL": 1,
        "LOCATION_CODE": "123"
    },
    {
        "ENTITY_ID": 2,
        "PARENT_EID": 1,
        "LOCATION_LEVEL": 2,
        "LOCATION_CODE": "234"
    },
    {
        "ENTITY_ID": 3,
        "PARENT_EID": 2,
        "LOCATION_LEVEL": 3,
        "LOCATION_CODE": "345"
    },
    {
        "ENTITY_ID": 4,
        "PARENT_EID": 1,
        "LOCATION_LEVEL": 2,
        "LOCATION_CODE": "567"
    },
    {
        "ENTITY_ID": 5,
        "PARENT_EID": 5,
        "LOCATION_LEVEL": 1,
        "LOCATION_CODE": "012"
    },
    {
        "ENTITY_ID": 6,
        "PARENT_EID": 5,
        "LOCATION_LEVEL": 2,
        "LOCATION_CODE": "023"
    }
]



fun hasChildren(id) = sizeOf(Input filter (($.PARENT_EID == id) and ($.ENTITY_ID != $.PARENT_EID)))

fun createTree(data) = if (hasChildren(data.ENTITY_ID) > 0)data ++ {"CHILDRENS": (Input filter (($.PARENT_EID == data.ENTITY_ID) and ($.ENTITY_ID != $.PARENT_EID))) map ((item, index) -> createTree(item)) } else data
---
Input filter ($.ENTITY_ID == $.PARENT_EID) map ((item, index) -> createTree(item))

Другие вопросы по теме