Neo4j syntax for WITH statement - neo4j

I am trying to auto generate a a text file that can be run to create the nodes and relationships for a Neoj4 Graph.
The text file is being created in two sections:
First the nodes are created in a For loop (6000 nodes) with a result like this:
create(SystemLogic_d6:FB {type:"SUB_DINT", instanceName:"d6", section:"SystemLogic"})
create(SystemLogic_d5:FB {type:"SUB_DINT", instanceName:"d5", section:"SystemLogic"})
create(SystemLogic_d7:FB {type:"ADD_DINT", instanceName:"d7", section:"SystemLogic"})
create(SystemLogic_d8:FB {type:"SEL", instanceName:"d8", section:"SystemLogic"})
Then in the next section of the text file relationships are created in another For loop wih a result like this:
MATCH (SystemLogic_d8:FB), (SystemLogic_d12:FB) WHERE SystemLogic_d8.instanceName = "d8" AND SystemLogic_d12.instanceName = "d12" CREATE (SystemLogic_d8)-[: c]->(SystemLogic_d12)
MATCH (SystemLogic_d17:FB), (SystemLogic_d18:FB) WHERE SystemLogic_d17.instanceName = "d17" AND SystemLogic_d18.instanceName = "d18" CREATE (SystemLogic_d17)-[: c]->(SystemLogic_d18)
MATCH (SystemLogic_d16:FB), (SystemLogic_d17:FB) WHERE SystemLogic_d16.instanceName = "d16" AND SystemLogic_d17.instanceName = "d17" CREATE (SystemLogic_d16)-[: c]->(SystemLogic_d17)
MATCH (SystemLogic_d11:FB), (SystemLogic_d5:FB) WHERE SystemLogic_d11.instanceName = "d11" AND SystemLogic_d5.instanceName = "d5" CREATE (SystemLogic_d11)-[: c]->(SystemLogic_d5)
This is giving the error WITH is required between CREATE and MATCH
I tried inserting a WITH in between as in this answer
Neo4j Cypher WITH is required between CREATE and MATCH:
Which gives a result like this:
MATCH (SystemLogic_d8:FB), (SystemLogic_d12:FB) WITH SystemLogic_d8,SystemLogic_d12 WHERE SystemLogic_d8.instanceName = "d8" AND SystemLogic_d12.instanceName = "d12" CREATE (SystemLogic_d8)-[: c]->(SystemLogic_d12)
MATCH (SystemLogic_d17:FB), (SystemLogic_d18:FB) WITH SystemLogic_d17,SystemLogic_d18 WHERE SystemLogic_d17.instanceName = "d17" AND SystemLogic_d18.instanceName = "d18" CREATE (SystemLogic_d17)-[: c]->(SystemLogic_d18)
MATCH (SystemLogic_d16:FB), (SystemLogic_d17:FB) WITH SystemLogic_d16,SystemLogic_d17 WHERE SystemLogic_d16.instanceName = "d16" AND SystemLogic_d17.instanceName = "d17" CREATE (SystemLogic_d16)-[: c]->(SystemLogic_d17)
MATCH (SystemLogic_d11:FB), (SystemLogic_d5:FB) WITH SystemLogic_d11,SystemLogic_d5 WHERE SystemLogic_d11.instanceName = "d11" AND SystemLogic_d5.instanceName = "d5" CREATE (SystemLogic_d11)-[: c]->(SystemLogic_d5)
MATCH (SystemLogic_FBI_1407:FB), (SystemLogic_FBI_1408:FB) WITH SystemLogic_FBI_1407,SystemLogic_FBI_1408 WHERE SystemLogic_FBI_1407.instanceName = "FBI_1407" AND SystemLogic_FBI_1408.instanceName = "FBI_1408" CREATE (SystemLogic_FBI_1407)-[: c]->(SystemLogic_FBI_1408)
But I still get the same error
I also tried putting the WITH statement after the create statement but that gives another error.
Are you able to import and run multiple node/relationships creation statements in this fashion?
It works fine for creating the nodes but I am new to using Neo4J / Cypher and I am not sure if it is my syntax that is incorrect or that you can't create multiple relatiionships in this fasion.
Thanks for your help

You need to separate the statements with a semicolon, Please refer following queries:
create(SystemLogic_d8:FB {type:"SEL", instanceName:"d8", section:"SystemLogic"});
create(SystemLogic_d9:FB {type:"SEL", instanceName:"d8", section:"SystemLogic"});
MATCH (SystemLogic_d2:FB), (SystemLogic_d21:FB) WHERE SystemLogic_d2.instanceName = "d8" AND SystemLogic_d21.instanceName = "d12" CREATE (SystemLogic_d2)-[: c]->(SystemLogic_d21);
MATCH (SystemLogic_d1:FB), (SystemLogic_d12:FB) WHERE SystemLogic_d1.instanceName = "d8" AND SystemLogic_d12.instanceName = "d12" CREATE (SystemLogic_d1)-[: c]->(SystemLogic_d12)
If you have only CREATE statements then there is no need to use semicolon it will work,
But if you are using MATCH and CREATE combined then you need to separate the statements with a semicolon.

#Raj answer is valid. However, as you are already capturing the nodes in your create statements, you do not need to perform a match on them to create relations.
Your file could then be :
create(SystemLogic_d6:FB {type:"SUB_DINT", instanceName:"d6", section:"SystemLogic"})
create(SystemLogic_d5:FB {type:"SUB_DINT", instanceName:"d5", section:"SystemLogic"})
create(SystemLogic_d7:FB {type:"ADD_DINT", instanceName:"d7", section:"SystemLogic"})
create(SystemLogic_d8:FB {type:"SEL", instanceName:"d8", section:"SystemLogic"})
CREATE (SystemLogic_d8)-[:c]->(SystemLogic_d6)
CREATE (SystemLogic_d7)-[:c]->(SystemLogic_d6)
CREATE (SystemLogic_d8)-[:c]->(SystemLogic_d5)

Related

How to verify if a node exist and if not exist then a created during an import of .csv to neo4j

I am importing some .cvs files for my database in neo4j, but I have the data of people in three different files, so when I import the data of the person from another file that has more data, I get an error when trying to import people nodes, because I already have other nodes with those dni (constraint) in my database.
So I want to create the new node or, if it exists, retrieve its pointer to create relationships with other nodes that I keep creating while I import.
I have tried several things on the internet but I still can't find the solution
Here my code:
LOAD CSV WITH HEADERS FROM 'file:/D:/ACCOUNT.csv' AS line FIELDTERMINATOR ';'
MERGE (persona :Persona { dni: line.DNI,
nombre: line.NOMBRE,
sexo: line.SEXO,
fechaNacimiento: line.FNACIMIENTO,
direccion: line.DIRECCION
})
I have tried with apoc and "with" but I still can't find the solution.
when this code finds another node with a person label and ID equal to the one entered, it gives me an error
To get this working, you'll have to understand how MERGE works. The statement
MERGE (persona :Persona { dni: line.DNI, nombre: line.NOMBRE, sexo: line.SEXO,
fechaNacimiento: line.FNACIMIENTO,direccion: line.DIRECCION
})
will create a new Persona node for every distinct combination of the above properties. So, for a node with the same dni, but with other values of other properties, this will fail. To fix this, you should try merging the nodes on the basis of their dni, and then set the properties like this:
MERGE (persona :Persona { dni: line.DNI })
ON CREATE
SET persona.nombre = line.NOMBRE,
persona.sexo = line.SEXO,
persona.fechaNacimiento = line.FNACIMIENTO,
persona.direccion = line.DIRECCION
The above query will ignore setting properties if a matching node is found. To set some properties when a match is found, use ON MATCH, like this:
MERGE (persona :Persona { dni: line.DNI })
ON CREATE
SET persona.nombre = line.NOMBRE,
persona.sexo = line.SEXO,
persona.fechaNacimiento = line.FNACIMIENTO,
persona.direccion = line.DIRECCION
ON MATCH
// Matching logic here

How can I get all posible paths between two nodes with Graphhopper

I'm trying to find all paths between 2 nodes by using graphhopper but there is something wrong with my code. When remove setAlgorith line, it returns only one path but when I add setAlgorithm(Parameters.Algorithms.ALT_ROUTE), it returns 0 path. Here is my code:
GraphHopper graphHopper = new GraphHopper().forServer();
graphHopper.load("E:\\graphhopper\\[asia_vietnam].osm-gh");
GHRequest req = new GHRequest(21.006399, 105.820359, 21.022409, 105.819163).
setAlgorithm(Parameters.Algorithms.ALT_ROUTE).
setLocale(Locale.US);
GHResponse rsp = graphHopper.route(req);
List<PathWrapper> paths = rsp.getAll();
System.out.println(paths.size());
According to this post, it should return all possible path but seems like it doesn't work.

Neo4j - poor performance

I receive daily a full csv file with all customers. I need to insert/update the neo4j database. So I am using this query:
I already create indexes on hash field.
MERGE (XFEWYX:CUSTOMER_BSELLER {hash:'xyz#hotmail.com'} ) ON CREATE SET XFEWYX.hash = 'xyz#hotmail.com',XFEWYX.name = 'XYZ ',XFEWYX.birthdate = '1975-05-20T00:00:00',XFEWYX.id = '1770852',XFEWYX.nick = 'CLARISSA',XFEWYX.documentNumber = 'XYZ',XFEWYX.email = 'clarissajuridica#hotmail.com' with XFEWYX
MERGE (WHHEKX:EMAIL {hash:'clarissajuridica#hotmail.com'} ) ON CREATE SET WHHEKX.hash = 'clarissajuridica#hotmail.com',WHHEKX.email = 'clarissajuridica#hotmail.com' with XFEWYX,WHHEKX
MERGE (JJKONT:DOCUMENT {hash:'06845078700'} ) ON CREATE SET JJKONT.document = 'XYZ',JJKONT.hash = '06845078700' with XFEWYX,WHHEKX,JJKONT
MERGE (MERUCB:PHONE {hash:'NoneNone'} ) ON CREATE SET MERUCB.areaCode = 'None',MERUCB.hash = 'NoneNone',MERUCB.number = 'None' with XFEWYX,WHHEKX,JJKONT,MERUCB
MERGE (BOORBT:PHONE {hash:'XYZ'} ) ON CREATE SET BOORBT.areaCode = '21',BOORBT.hash = 'XYZ',BOORBT.number = 'XYZ' with XFEWYX,WHHEKX,JJKONT,MERUCB,BOORBT
MERGE (XBLZNF:PHONE {hash:'XYZ'} ) ON CREATE SET XBLZNF.areaCode = '21',XBLZNF.hash = 'XYZ',XBLZNF.number = 'XYZ' with XFEWYX,WHHEKX,JJKONT,MERUCB,BOORBT,XBLZNF
MERGE (XFEWYX)-[:REGISTERED_WITH {optin:'false'}]->(WHHEKX)
MERGE (XFEWYX)-[:DOCUMENT]->(JJKONT)
MERGE (XFEWYX)-[:COMMERCIAL_PHONE]->(MERUCB)
MERGE (XFEWYX)-[:PHONE]->(XBLZNF)
MERGE (XFEWYX)-[:CELL_PHONE]->(BOORBT)
Does anyone have another approach how to execute this query?
I would try using the PROFILE command. You might put a LIMIT on your LOAD CSV (I assume you're using LOAD CSV) for the testing.
I would also check out this article:
http://www.markhneedham.com/blog/2014/10/23/neo4j-cypher-avoiding-the-eager/
Some of that has been fixed in recent versions of Neo4j, but you have an awful lot of MERGEs there, so you probably could stand to split some of that up and process your CSV file more than once.

Using python list as node properties in py2neo

I have a list of urls:
urls = ['http://url1', 'http://url2', 'http://url3']
Mind you the list can have any number of entries including 0 (none). I want to create new node property for each url (list entry).
Example how the node will look like
(label{name='something', url1='http://url1', url2='http://url2'}, etc...)
It is possible to expand a dictionary with ** with the same effect I need but is there any way to do this with a list?
You can put your list in a dictionary and use this to create a node:
from py2neo import Node
urls = ['http://1', 'http://2']
props = {}
for i, url in enumerate(urls):
# get a key like 'url1'
prop_key = 'url' + str(i)
props[prop_key] = url
my_node = Node('Person', **props)
graph.create(my_node)

Neo4j Relationships not showing connecting lines in the graph

I created the following nodes and relationship in neo4j
CREATE (United_States:Citizenship { type : “Naturalized”})
CREATE (United_States:Citizenship { type : “Native_Born”})
CREATE (uid:Person { unique_id: 'A23AF39D-BEED-4FFC-B080-1362920FA7A8', id_type: '128bit_UUID' })
MATCH (uid:Person),(Native_Born:Citizenship) WHERE uid:Person="A23AF39D-BEED-4FFC-B080-1362920FA7A8" CREATE (uid) <- [ r:PersonUniqueIdentifier ] -> (Native_Born)
CREATE (fn:Person { first_name:'Willie', id_type:'128bit_UUID'})
CREATE (ln:Person { last_name:'Armstrong', id_type:'128bit_UUID'}))
CREATE CONSTRAINT ON (uid:Person) ASSERT Person.unique_id IS UNIQUE
CREATE INDEX ON :Person(unique_id)
I do not see the 'PersonUniqueIdentifier' Relation between the Citizenship node and id:Person node on the graph.
Screen shot of graph
Firstly, I would make a habit of doing the indexes/constraints first. There's not a lot of data here, but if you add an index after adding the data, it will need to go through all your nodes first. Also, creating a constraint also adds an index for you, so no need for that line. It seems like you're mixing up variables here, so refactoring a bit:
CREATE CONSTRAINT ON (person:Person) ASSERT person.unique_id IS UNIQUE
Also your Citizenship CREATEs are using the same variable name. I don't know if that would necessarily cause a problem, but it's simpler to do this anyway:
CREATE (:Citizenship { type : “Naturalized”}), (:Citizenship { type : “Native_Born”})
This statement looks fine to me (though, again, you could lose the variable if you wanted to):
CREATE (person:Person { unique_id: 'A23AF39D-BEED-4FFC-B080-1362920FA7A8', id_type: '128bit_UUID' })
Here there are a few problems. Here's how I would refactor it:
MATCH (person:Person),(citizenship:Citizenship)
WHERE
person.unique_id="A23AF39D-BEED-4FFC-B080-1362920FA7A8",
citizenship.type = 'Native_Born'
CREATE (person)-[:HAS_CITIZENSHIP]->(citizenship)
I'm not really sure what you want to do here. It seems like you want to create one person, so I would do this:
CREATE (:Person { first_name:'Willie', id_type: '128bit_UUID', last_name:'Armstrong'})

Resources