I am trying to accomplish something quite simple in python but not so in Neo4j. I'd appreciate any comment and suggestions to improve the procedure!
Within Python script, I am trying to create a relationship as well as its property for every pair of two nodes. From a data analysis (not a csv file), I ended up having a dataframe with three columns as following:
name1 name2 points
===========================
Jack Sara 0.3
Jack Sam 0.4
Jack Jill 0.2
Mike Jack 0.4
Mike Sara 0.5
...
From this point, I would like to create all nodes for the people: Jack, Sara, Sam, Mike, etc and as well as their relationship with a property name points.
First I tried to match all nodes and then use "FOREACH" to update the relationship property one at a time.
tx = graph.cypher.begin()
qs2 = "MATCH (p1:person {name:"Jack"}), (p2:person)
WHERE p2.name IN ["Sara","Jill","Mike"]
FOREACH (r IN range(10) |
CREATE (p1)-[:OWES TO {score:{score_list}[r]}]->(p2))"
Above statement does not return what I expected. Instead of matching one node to another, it calls all nodes in p2 and create the relationship between the paris, resulting multiple copies of the same information.
Is there a notation to indicate one node at a time? If you think there is a better approach than above, please do share with me. Thank you!
The easiest approach would be to export the data to be imported into csv file and use then the LOAD CSV
command in cypher.
LOAD CSV WITH HEADERS FROM <url> AS csvLine
MATCH (p1:Person {name:csvLine.name1}), (p2:Person {name:csvLine.name2})
CREATE (p1)-[:OWES_TO {score:csvLine.points}]->(p2)
In case you cannot use that approach you can use a parameterized Cypher statement using the transactional http endpoint. The parameter is a single element map containing an array of your data structure. On http level the request body would look like:
{
"statements": [
{
"parameters": {
"data": [
{
"name1": "Jack", "name2": "Sara", "points": 0.3
},
{
"name1": "Jack", "name2": "Sam", "points": 0.4
},
{
"name1": "Jack", "name2": "Jill", "points": 0.2
} // ...
]
},
"statement": "UNWIND {data} AS row
MATCH (p1:Person {name:row.name1}), (p2:Person {name:row.name2})
CREATE (p1)-[:OWES_TO {row.points}]->(p2)"
}
]
}
Q: How can I create the parameters from pyhton? A: use the python json module
import json
json.dumps({'data':[{'name1':'Jack', 'name2':'Sara', 'points':0.3},{'name1':'Jack', 'name2':'Sam', 'points':0.4}]})