Dataweave - 如何将项目数组转换为 Dataweave 中的父子关系

Dataweave - How to transform array of items into parent child relation in Dataweave

我想使用数据编织转换将以下输入转换为父子 JSON 输出。请让我知道以前是否有人从事过此工作。我在下面添加了示例输入和输出 json。

已更新 post 添加更多节点:我想要多个父节点,其位置级别为 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"
              }]
    }
]

试一试:

%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)
) 

使用更多输入对其进行测试,如果其他一些测试用例失败,您可能需要调整代码。

与像我一样构建 nodechildren 变量相比,您(或其他人)可能想使用 update 运算符重写此代码。

%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))