pythonforeachneo4jrelation

Creating relations between countries in neo4j using python


I need help with creating relations between countries in neo4j using python. I have a code, but in neo4j browser it doesn't create relations.

from neo4j import GraphDatabase
driver = GraphDatabase.driver("neo4j://localhost:7687",
                              auth=("neo4j", "test"))

def create_country(tx, name,continent,population_mln,govrm_system,bcountry):
    tx.run("CREATE (a:Country {name: $name,continent: $continent,population_mln: $population_mln,govrm_system:$govrm_system,bcountry: $bcountry})",
           name=name,continent=continent,population_mln=population_mln,govrm_system=govrm_system,bcountry=bcountry)

with driver.session() as session:
    session.execute_write(create_country, "russia","Asia",143,"terrorist state",["Kazakhstan","Lithuania","Finland","China","Japan"])
    session.execute_write(create_country, "India","Asia",1393,"Parliamentary Republic","China")
    session.execute_write(create_country, "China","Asia",1412,"One-party state",["India","russia","Philipines","Japan"])
    session.execute_write(create_country, "Poland","Europe",37,"Parliamentary Republic",["Lithuania","Germany","Czechia"])
    session.execute_write(create_country, "Kazakhstan","Asia",19,"Presidential system Republic","russia")
    session.execute_write(create_country, "Lithuania","Europe",2.7,"Parliamentary Republic",["russia","Poland"])
    session.execute_write(create_country, "Finland","Europe",5.5,"Parliamentary Republic","russia")
    session.execute_write(create_country, "Philipines","Asia",111,"Parliamentary Republic",["Japan","China"])
    session.execute_write(create_country, "Japan","Asia",125,"Constitutional Monarchy",["Philipines","China","russia"])
    session.execute_write(create_country, "Germany","Europoe",83,"Parliamentary Republic",["Czechia","Austria","Poland"])
    session.execute_write(create_country, "Czechia","Europoe",10,"Parliamentary Republic",["Austria","Poland","Germany"])
    session.execute_write(create_country, "Austria","Europoe",9,"Parliamentary Republic",["Czechia","Germany"])

def create_bordering_country(tx, name, bcountry):
    tx.run("FOREACH (n IN a.bcountry | MERGE (bcountry:Country {name: n}) MERGE (a)-[:HAS_BORDER_WITH]-(bcountry))") 

It should look like this:

enter image description here

What I get in neo4j:

enter image description here

I also tried to do like this, but then I get duplicates of countries:

def create_bordering_country(tx, name, bcountry):
    tx.run("MATCH (a:Country) WHERE a.name = $name "
           "MERGE (a)-[:HAS_BORDER_WITH]-(:Country {name: $bcountry}) RETURN DISTINCT a.name",
           name=name, bcountry=bcountry)

session.execute_write(create_bordering_country, "russia", "China")
    session.execute_write(create_bordering_country, "India", "China")
    session.execute_write(create_bordering_country, "russia", "Kazakhstan")
    session.execute_write(create_bordering_country, "russia", "Lithuania")
    session.execute_write(create_bordering_country, "russia", "Finland")
    session.execute_write(create_bordering_country, "Poland", "Lithuania")
    session.execute_write(create_bordering_country, "China", "Japan")
    session.execute_write(create_bordering_country, "Russia", "Japan")
    session.execute_write(create_bordering_country, "Philipines", "Japan")
    session.execute_write(create_bordering_country, "Philipines", "China")
    session.execute_write(create_bordering_country, "Germany", "Poland")
    session.execute_write(create_bordering_country, "Austria", "Poland")
    session.execute_write(create_bordering_country, "Czechia", "Poland")
    session.execute_write(create_bordering_country, "Czechia", "Austria")
    session.execute_write(create_bordering_country, "Czechia", "Germany")
    session.execute_write(create_bordering_country, "Germany", "Austria") 

Solution

  • You are getting duplicates because merge will create more bcountry even if it exists already. Please use below new query.

    Function: create_bordering_country

    Old code:

     MATCH (a:Country) WHERE a.name = $name 
     MERGE (a)-[:HAS_BORDER_WITH]-(:Country {name: $bcountry}) 
     RETURN DISTINCT a.name
    

    New code:

     MERGE (a:Country) WHERE a.name = $name 
     MERGE (b:Country) WHERE b.name = $bcountry 
     MERGE (a)-[:HAS_BORDER_WITH]-(b) 
     RETURN a.name