Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
01-21-2021 03:44 AM
Hi, I am very new to Neo4j and have followed as many tutorials as I can make sense of but I am stuck with what i am actually trying to do and I am wondering if it is because of the data structure that I am working wth. I have a JSON file that contains data for class dependencies, not a deeply nested format, a snippet of which looks like this
[
{
"id": 1,
"name": "ER00",
"isroot": false,
"isabstract": false,
"isUsedBy": ,
"dependsOn": [
{
"id": 2,
"name": "ERScheme",
"isroot": false,
"isabstract": false,
"isUsedBy": ,
"dependsOn":
}
]
},
{
"id": 2,
"name": "ERScheme",
"isroot": false,
"isabstract": false,
"isUsedBy": [
{
"id": 1,
"name": "ER00",
"isroot": false,
"isabstract": false,
"isUsedBy": ,
"dependsOn":
},
],
"dependsOn":
}
]
I am using this cypher to load the JSON and create the database.
MATCH (n) DETACH DELETE n;
//Basic Load
:param url => "file:///Dependencies_Tree_Full_UnSorted.json";call apoc.load.json($url) yield value
//return value
unwind value as n
merge (e:Entity {name: n.name})
set e.entityId = value.idwith e, n
unwind n.dependsOn as depOn
unwind n.isUsedBy as usdBy
merge (d:Dependant {name: depOn.name})
set d.entityId = depOn.id
merge (u:UsedBy {name: usdBy.name})
set u.entityId = usdBy.idmerge (d)-[:Depends_On]-(e)
merge (e)-[:Used_By]-(u)
This does not seem to create the graph and relationships as I would expect. For example if I use this query
> match (e:Entity)-[:Depends_On]-(d:Dependant) where e.name = "ERScheme" return e,d
then I dont get the expected result. I would expect to see 'ER00' and 'ERScheme' returned but I get nothing. I must be missing something simple, any pointers please?
***** EDIT ******
I have now try changing my incoming data structure to have the following format
{
"nodes": [
{
"id": 1,
"text": "BankAccount",
"isroot": false,
"children": [
{
"id": 2,
"text": "AccountType",
"isroot": false,
"children": []
},
{
"id": 145,
"text": "Branch",
"isroot": false,
"children": []
},
{
"id": 146,
"text": "BranchContact",
"isroot": false,
"children": []
},
{
"id": 185,
"text": "ChequeBookHeldBy",
"isroot": false,
"children": []
},
{
"id": 299,
"text": "Group",
"isroot": false,
"children": []
},
{
"id": 176,
"text": "Member",
"isroot": false,
"children": []
},
{
"id": 401,
"text": "MessageSchemaEntity",
"isroot": false,
"children": []
},
{
"id": 167,
"text": "SchemeRelation",
"isroot": false,
"children": []
},
{
"id": 357,
"text": "SchemeSSAS",
"isroot": false,
"children": []
}
]
},
{
"id": 2,
"text": "AccountType",
"isroot": false,
"children": [
{
"id": 401,
"text": "MessageSchemaEntity",
"isroot": false,
"children": []
}
]
},
],
"links": [
{
"source": 2,
"target": 1,
"sourcetext": "AccountType",
"targettext": "BankAccount"
},
{
"source": 145,
"target": 1,
"sourcetext": "Branch",
"targettext": "BankAccount"
}
]
}
I am still strugling as to how to import this data and create the relationships between 'nodes' and 'links'. My first attempt at loading takes an absolute age to load and then when complete but does not have the relationships specified
MATCH (n) DETACH DELETE n;
//Basic Load
:param url => "file:///Dependencies_Force_Direct.json";
call apoc.load.json($url) yield value
//return value
unwind value.nodes as nd
merge (n:Node {name: nd.text, nodeId: nd.id})
with value, n
unwind value.links as links
//merge (l:Link {name: lk.sourcetext, nodeId: lk.source})
foreach (lk in links |
//merge (l:Link {name: lk.sourcetext, nodeId: lk.source})
//merge (lk.sourcetext)[:Depends_On]-(lk.targettext)
//merge (lk.targettext)[:Used_By]-(lk.sourcetext)
merge (s:Source {name: lk.sourcetext})
merge (t:Target {name: lk.targettext})
)
And hen I do try to specify the relationships I am getting an error stating 's' is not defined
MATCH (n) DETACH DELETE n;
//Basic Load
:param url => "file:///Dependencies_Force_Direct.json";
call apoc.load.json($url) yield value
//return value
unwind value.nodes as nd
merge (n:Node {name: nd.text, nodeId: nd.id})
with value, n
unwind value.links as links
//merge (l:Link {name: lk.sourcetext, nodeId: lk.source})
foreach (lk in links |
//merge (l:Link {name: lk.sourcetext, nodeId: lk.source})
//merge (lk.sourcetext)[:Depends_On]-(lk.targettext)
//merge (lk.targettext)[:Used_By]-(lk.sourcetext)
merge (s:Source {name: lk.sourcetext})
merge (t:Target {name: lk.targettext})
)
with n, s, t
merge (n)-[:Depends_On]-(s)
merge (n)-[:Used_By]->(t)
I am getting so confused!
01-23-2021 06:21 AM
You probably didn't create a constraint on Node(nodeId)
you should also only merge on the id field and set the name separately
your first unwind increases the cardinality to the number of nodes
so you want to use WITH distinct value
call apoc.load.json($url) yield value
unwind value.nodes as nd
merge (n:Node {nodeId: nd.id})
ON CREATE SET n.name = nd.text
// reduce cardinality
with distinct value
unwind value.links as links
// find source and target node
match (n1:Node {nodeId: lk.source})
match (n2:Node {nodeId: lk.target})
// create relationship (one direction is enough, 2 relationships are waste
merge (n1)-[:Depends_On]->(n2)
01-23-2021 09:34 AM
Excellent, thank you, this has got me going again. I have other questions now but I will make a separate post so as not to hijack this one.
All the sessions of the conference are now available online