Reputation: 11
I want to convert the below input into parent-child JSON output using dataweave transform. Please let me know if anybody worked on this before. I've added a sample input and output json below.
Updated post with additional nodes: I want multiple parent nodes with location level=1 with respective hierarchies.
Input json format:
[
{
"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"
}
]
Output json format:
[
{
"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"
}]
}
]
Upvotes: 0
Views: 642
Reputation: 1
%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))
Upvotes: 0
Reputation:
Give this a try:
%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)
)
Test it with more inputs and you may need to adjust the code if some other test cases fail.
You (or maybe someone else) may want to rewrite this using the update
operator as compared building the node
and the children
variables like I do.
Upvotes: 0