Split on multiple levels

It feels like I did this 100 times. but I can seem to find an old example..

load csv with headers from "file:///RedTeams.csv" as row with row
ForEach(_ In Case When (row.RedTeam is not null) Then [1] Else End|
merge (redTeam:RedTeam{Name:trim(row.RedTeam)})
ForEach(_ In Case When (row.Member is not null) Then [1] Else End|
merge (member:Member{Name:trim(row.Member)})
merge (redTeam)-[hasMemberRel:hasMember]->(member)
ForEach(skills in split(row.Skills, ';') |
ForEach(_ IN CASE WHEN skills <> '' Then [1] Else End|
// Start: does not work section
merge (test:Test{Name:trim(skills)}) // test:Name has first and second parts
merge (skill:Skill{Name:trim(split(skills, '|') )[0]})
merge (member)-[knowsRel:knows]->(skill)
set skill.level = trim(split(skills, '|') )[1]
// End: does not work section

     ) // end skills  <> ''
  ) // split(row.Skills, ';')

) // row.Member is not null
) // row.RedTeam is not null

here is a simple dataset..
RedTeam,Member,Skills
RedTeam01,RT01-Mem01,Server-Vul1|High;DB-Vul6|Medium
RedTeam01,RT01-Mem02,Server-Vul2|Medium;DB-Vul6|High
RedTeam01,RT01-Mem03,Server-Vul2|High;
RedTeam02,RT02-Mem01,DB-Vul6|Medium;
RedTeam02,RT02-Mem02,DB-Vul6|Medium;
RedTeam02,RT02-Mem03,Server-Vul1|Medium;Server-Vul2|Medium

Thanks.. sorry to bother you, just cant seem to examples of how i always did this in the past.. sorry

This executes:

load csv with headers from "file:///RedTeams.csv" as row 
with row
ForEach(_ In Case When (row.RedTeam is not null) Then [1] Else [] End|  
    merge (redTeam:RedTeam{Name:trim(row.RedTeam)})
    ForEach(_ In Case When (row.Member is not null) Then [1] Else [] End|
        merge (member:Member{Name:trim(row.Member)})
        merge (redTeam)-[hasMemberRel:hasMember]->(member)
        ForEach(skills in split(row.Skills, ';') |
            ForEach(_ IN CASE WHEN skills <> '' Then [1] Else [] End|
                // Start: does not work section
                merge (test:Test{Name:trim(skills)}) // test:Name has first and second parts
                merge (skill:Skill{Name:trim(split(skills, '|')[0])})
                merge (member)-[knowsRel:knows]->(skill)
                set skill.level = trim(split(skills, '|')[1])
                // End: does not work section
            ) // end skills  <> ''
        ) // split(row.Skills, ';')
  ) // row.Member is not null
) // row.RedTeam is not null

I think this refactored query will produce the same results:

load csv with headers from "file:///RedTeams.csv" as row 
with row
where row.RedTeam is not null
merge (redTeam:RedTeam{Name:trim(row.RedTeam)})
with row, redTeam
where row.Member is not null
merge (member:Member{Name:trim(row.Member)})
merge (redTeam)-[:hasMember]->(member)
with row, member
forEach(skills in [i in split(row.Skills, ';') where i <> ''] |
    merge (test:Test{Name:trim(skills)})
    merge (skill:Skill{Name:trim(split(skills, '|')[0])})
    merge (member)-[knowsRel:knows]->(skill)
    set skill.level = trim(split(skills, '|')[1])
)

This one too, if you prefer the use of unwind vs forEach

load csv with headers from "file:///RedTeams.csv" as row 
with row
where row.RedTeam is not null
merge (redTeam:RedTeam{Name:trim(row.RedTeam)})
with row, redTeam
where row.Member is not null
merge (member:Member{Name:trim(row.Member)})
merge (redTeam)-[:hasMember]->(member)
with row, member
unwind [i in split(row.Skills, ';') where i <> '' | trim(i)] as skills
with skills, member, [i in split(skills, '|') | trim(i)] as skillsArray
merge (test:Test{Name:skills})
merge (skill:Skill{Name:skillsArray[0]})
merge (member)-[knowsRel:knows]->(skill)
set skill.level = skillsArray[1]

Thanks You Gary.. Thanks man for helping me out! AGAIN.. :) thanks man

1 Like