cancel
Showing results for 
Search instead for 
Did you mean: 

Join the community at Nodes 2022, our free virtual event on November 16 - 17.

Deeply nested JSON. Help with UNWIND/FOREACH?

FourMoBro
Node Clone

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.

1 ACCEPTED SOLUTION

FourMoBro
Node Clone

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.

View solution in original post

1 REPLY 1

FourMoBro
Node Clone

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.