Import nodes from recursively structured json

Hello,
How would I go about creating a cypher query that imports and merges Nodes which are inside json of type:
groups -> groups .. * .. groups

groups within groups within groups
groups may also be shared amongst other groups
all of the same type
all of the same relationship
The nesting can be 'n' deep so a fixed number of UNWIND/FOREACH isn't possible.

sample json:

{
	"ID": "ROOT",
	"groups": [
		{
			"ID": "GROUP_A6",
			"groups": [
				{
					"ID": "GROUP_B6"
				}
			]
		},
		{
			"ID": "GROUP_A5",
			"groups": [
				{
					"ID": "GROUP_X2",
					"groups": [
						{
							"ID": "GROUP_C1",
							"groups": []
						}
					]
				}
			]
		},
		{
			"ID": "GROUP_A1",
			"groups": [
				{
					"ID": "GROUP_B1",
					"groups": [
						{
							"ID": "GROUP_C1",
							"groups": []
						}
					]
				}
			]
		},
		{
			"ID": "GROUP_A2",
			"groups": [
				{
					"ID": "GROUP_B2",
					"groups": [
						{
							"ID": "GROUP_C1",
							"groups": []
						},
						{
							"ID": "GROUP_C2",
							"groups": []
						},
						{
							"ID": "GROUP_D2",
							"groups": []
						}
					]
				},
				{
					"ID": "GROUP_E2",
					"groups": [
						{
							"ID": "GROUP_F2",
							"groups": []
						},
						{
							"ID": "GROUP_G2",
							"groups": [
								{
									"ID": "GROUP_F2",
									"groups": []
								}
							]
						}
					]
				}
			]
		},
		{
			"ID": "GROUP_A4"
		},
		{
			"ID": "GROUP_A3",
			"groups": [
				{
					"ID": "GROUP_X2",
					"groups": [
						{
							"ID": "GROUP_C1",
							"groups": []
						}
					]
				}
			]
		}
	]
}

I took a crack at solving this and I think I have a solution that works. It is not that elegant but I might get back to it later.

It uses the apoc.load.json and its ability to use a json path. It does it in two passes. The first pass it gets every group ID key and in the second pass it looks up each groupid and gets its children. Then it merges each parent and child in the graph and connects them with one another.

// file with json data
WITH 'file:///somedirectory/recursive.json' AS json_file

// get all of the ID values
CALL apoc.load.json(json_file,"$..ID") YIELD value AS result
WITH json_file, result.result AS keys

// for each ID value get all of the children
UNWIND range(0,size(keys)-1) AS i
CALL apoc.load.json(json_file,"$..[?(@.ID == '" + toString(keys[i]) + "')].groups[*].ID") YIELD value AS children

// create the parents and children and link them up
WITH keys[i] AS parent_key, children.result AS children
MERGE (parent:GroupNode {name: parent_key})
WITH parent, children
UNWIND children as child_key
MERGE (child:GroupNode {name: child_key})
MERGE (child)-[:CHILD_OF]->(parent)
RETURN *
1 Like