I am working on Cypher query using UNWIND and Foreach in Neo4j. I am sure there is a bug, but I cannot figure out where I did wrong.
I am building a graph with three spans in a trace as follows (in "test.json")
[
{
"spanId":"3",
"name": "checkOut",
"parentId": ["1"],
"service_name": "svc"
},
{
"spanId":"2",
"name": "addCart",
"parentId": ["1"],
"service_name": "svc"
},
{
"spanId":"1",
"name": "frontend",
"service_name": "svc"
}
]
Span checkOut
and addCart
are child of front
, so there are parent-child relationships between frontend -> checkOut
and frontend -> addCart
.
Meanwhile, these spans all belong to "svc" service, so they should have relationship to "svc". However, frontend
misses the relation to "svc". See below
My Cypher query is as follows:
WITH 'file:///test.json' AS url
CALL apoc.load.json(url) YIELD value
MERGE (s:Span {span_id: value.spanId})
ON CREATE SET s.name=value.name, s.service=value.service_name
WITH s, value
UNWIND value.parentId AS parent
MERGE (p:Span {span_id: parent})
MERGE (p)-[:PARENT_OF]->(s)
WITH s, value, value.service_name AS ki
FOREACH(k IN ki |
MERGE (svc:Service{service: value.service_name} )
MERGE (s)-[:FROM_SERVICE]->(svc)
)
Can someone help me see where I did wrong in the Cypher query? A ton of thanks!
The problem is in the UNWIND
statement, your frontend
object doesn't have a parentId
array, so there is nothing to unwind there and the object gets lost, before creating a relationship to service. To fix this, you should move the creation and merge of relationship with service above UNWIND
. Try this:
WITH 'file:///test.json' AS url
CALL apoc.load.json(url) YIELD value
MERGE (s:Span {span_id: value.spanId})
ON CREATE SET s.name=value.name, s.service=value.service_name
WITH s, value, value.service_name AS ki
FOREACH(k IN ki |
MERGE (svc:Service{service: value.service_name} )
MERGE (s)-[:FROM_SERVICE]->(svc)
)
UNWIND value.parentId AS parent
MERGE (p:Span {span_id: parent})
MERGE (p)-[:PARENT_OF]->(s)