Deeply nested JSON. Help with UNWIND/FOREACH?

Good evening, folks. I am running apoc.load.json linked to a web API. That API returns a JSON object which is large and deeply nested. I have to admit that working between objects and arrays and lists and objects and more objects, etc is one of my weak points. At any rate, the API returns something that resembles this:

{
    "level1Akey": "level1Avalue",
    "level1Bkey": "level1Bvalue",
    "level1Ckey": {
        "level2Ckey": {
            "level3Ckey1":[
                {
                    "level4Ckey101":"level4Cvalue101",
                    "level4Ckey102":"level4Cvalue102",
                    "level4Ckey103":"level4Cvalue103"
                }
            ],
            "level3Ckey2":[
                {
                    "level4Ckey101":"level4Cvalue201",
                    "level4Ckey102":"level4Cvalue202",
                    "level4Ckey103":"level4Cvalue203"
                }
            ]
        }
    }
}

My goal is to create some nodes based upon the level4 keys/values, with relationships to existing nodes based upon the level1 key/value pairs. The hard part for me is getting down to the level 4 information. For each API request, the "level2" key will be different, but there is only one. There will be numerous "level3" keys and these will always be different, but their values for me are irrelevant. I just want to get beneath them.

The cypher would look something like this:

CALL apoc.load.json("url")
YIELD value
UNWIND value.level1Ckey as level2

some more unwinds.....please help...maybe FOREACH?

MATCH(e:Existing {name:value.level1Akey})
CREATE(n:New {name:xxx.level4Ckey101}, etc)
CREATE(n)-[:SOME_REL]->(e)

Any help would be appreciated.

Well, after sleeping on it, I remembered seeing a apoc.map.values function in a video. After a few iterations, I was able to solve my problem. The final code looks something like this:

CALL apoc.load.json("test.json")
YIELD value
WITH value
MATCH (e:Existing {name:value.level1Akey})
UNWIND value.level1Ckey as l2
UNWIND apoc.map.values(l2, keys(l2)) as l3
UNWIND apoc.map.values(l3, keys(l3)) as l4
FOREACH (item in l4 | 

MERGE (n:New {name:item.level4Ckey101, desc:item.level4Ckey102, other:item.level4Ckey103, etc...})
MERGE (n)-[:SOME_REL]->(e))

I am open to other or better solutions if someone has an idea to share.

1 Like