How to use cypher to create multiple edges for a graph in neo4j? - neo4j

I want to create a data graph in neo4j with cypher like the one in this figure.
create (v1:D)-[]->(v2:C)
create (v1:D)-[]->(v3:A)
create (v1:D)-[]->(v4:B)
create (v2:C)-[]->(v1:D)
create (v2:C)-[]->(v3:A)
create (v3:A)-[]->(v1:D)
create (v3:A)-[]->(v2:C)
create (v4:B)-[]->(v1:D)
Is it possible to create such a graph in cypher rather than using csv import from neo4j? One thing we need is the identifiers for the created nodes.
update: the neo4j version is 5.3.0

You are using CREATE command, that's why multiple nodes are getting created. Try using MERGE:
MERGE (a:A{id: randomUUID()})
MERGE (b:B{id: randomUUID()})
MERGE (c:C{id: randomUUID()})
MERGE (d:D{id: randomUUID()})
MERGE (a)-[r1:R{id: randomUUID()}]->(b)
MERGE (b)-[r2:R{id: randomUUID()}]->(c)
MERGE (a)-[r3:R{id: randomUUID()}]->(c)
MERGE (c)-[r4:R{id: randomUUID()}]->(d)
RETURN a,b,c,d, r1,r2,r3,r4

Related

Neo4j consolidate nodes in cypher single node relationship

I’m desperately trying to understand how to consolidate nodes in Neo4J for a more streamlined relationship.
I have a dataset with four columns: Person_1_ID, Person_1_Name, Person_2_ID, Person_2_Name
How do you consolidate IDs when they exist in two columns so that you only show one node?
For example:
My dataset looks like this:
If I do a simple match and merge like this:
LOAD CSV WITH HEADERS FROM 'file:///users.csv' AS row
MATCH (Person_1:Person_1 {Person_1_ID: row.Person_1_ID})
MATCH (Person_2:Person_2 {Person_2_ID: row.Person_2_ID })
MERGE (Person_2)-[pr:REFERRING]->(Person_1);
It produces this:
I'm trying to merge on names/IDs so that the relationships look like this:
Desperately trying to understand how you merge nodes properly here so that the relationships are consolidated. Any guidance and code example is greatly appreciated!
Doug
You have a couple of issues:
In your initial node import, don't use Person_1 and Person_2 node labels. Just stick with a single node label Person. The same goes for person id node property. If I were you, I would just delete existing graph and use the following Cypher to produce the desired results:
LOAD CSV WITH HEADERS FROM 'file:///users.csv' AS row
MERGE (Person_1:Person {id: row.Person_1_ID})
MERGE (Person_2:Person {id: row.Person_2_ID })
MERGE (Person_2)-[pr:REFERRING]->(Person_1);

Neo4j create graph that some nodes have more than one relationships

Over my Neo4j I want to create this graph:
SO I tried to create some nodes and relationships with:
MERGE (D:POINT {NAME:'d'})<-[:LINKS]-(A:POINT {NAME:'a'})-[:LINKS]->(B:POINT {NAME:'b'})-[:LINKS]->(C:POINT {NAME:'c'})
But I cannot find out how I will create the relationships between D and B points also I cannot find out how I will link the A and C as well.
Do you have any Idea how to do that?
In order to avoid unintentionally creating duplicate nodes and/or relationships, you must invoke MERGE on individual nodes and relationships.
To quote the dev manual:
When using MERGE on full patterns, the behavior is that either the
whole pattern matches, or the whole pattern is created. MERGE will not
partially use existing patterns — it’s all or nothing. If partial
matches are needed, this can be accomplished by splitting a pattern up
into multiple MERGE clauses.
For example, to properly create your graph without any duplicate nodes or relationships:
MERGE (A:POINT {NAME:'a'})
MERGE (B:POINT {NAME:'b'})
MERGE (C:POINT {NAME:'c'})
MERGE (D:POINT {NAME:'d'})
MERGE (A)-[:LINKS]->(B)
MERGE (A)-[:LINKS]->(C)
MERGE (A)-[:LINKS]->(D)
MERGE (B)-[:LINKS]->(C)
MERGE (D)-[:LINKS]->(B)
CREATE seems to be the natural way to me for creating nodes and relationships.
CREATE (D:POINT {NAME:'d'})<-[:LINKS]-(A:POINT {NAME:'a'})
, (A)-[:LINKS]->(B:POINT {NAME:'b'})<-[:LINKS]-(D)
, (B)-[:LINKS]->(C:POINT {NAME:'c'})<-[:LINKS]-(A)
You can do it by doing a MATCH before a MERGE eg. FOR the relationship between A and D do:
MATCH (A:POINT {NAME:'a'}),(B:POINT {NAME:'d'}) MERGE (A)-[:LINKS]->(B)

neo4j multiple create cypher commands vs batch insert

I am new to neo4j and creating a node through cypher command.
I followed movie Graph example where I can create multiple nodes and relationship in single command :
CREATE (TheMatrix:Movie {title:'The Matrix', released:1999, tagline:'Welcome to the Real World'})
CREATE (Keanu:Person {name:'Keanu Reeves', born:1964})
CREATE (Carrie:Person {name:'Carrie-Anne Moss', born:1967})
CREATE (Laurence:Person {name:'Laurence Fishburne', born:1961})
CREATE (Hugo:Person {name:'Hugo Weaving', born:1960})
Neo4j also gives batch operations API http://neo4j.com/docs/milestone/rest-api-batch-ops.html. I want to build a library to create and update node and relationship, which option should I choose?

Cypher create path in single query

Is it possible to create the following path in a single cypher query?
Path:
https://drive.google.com/file/d/0B3WHeKW1--8qajZRQmlBN082UG8/view?usp=sharing
Anyone any ideas?
The trick is that you can use as many CREATE and MERGE blocks as you like.
CREATE (a), (b), (c)
MERGE (a)-[:foo]->(b)
MERGE (a)-[:foo]->(c)
RETURN a,b,c;

Adding relationship to existing nodes with Cypher

I'm trying out Neo4j for the first time. I'm using the 2.0-RC1 community edition.
I've created some nodes:
MERGE (u:User{username:'admin',password:'admin'})
MERGE (r1:Role{name:'ROLE_ADMIN'})
MERGE (r2:Role{name:'ROLE_WEB_USER'})
MERGE (r3:Role{name:'ROLE_REST_USER'})
and now I want to add relationships between the nodes. However, I don't want to clear out the existing database created with the script above, add the statements and run it again. I want to add relationships to the existing nodes. Google helped me find this:
START n=node(*), m=node(*)
where has(n.username) and has(m.name) and n.username = 'admin'
and m.name = 'ROLE_WEB_USER'
create (n)-[:HAS_ROLE]->(m)
Which works fine (even though I don't understand all the syntax). However, I am aware that this finds any node with a username property and any node with a name property, instead of using labels to check that it has the right type of node.
How can I do the same using labels?
In Neo4j 2.0 you can create schema indexes for your labels and the properties you use for lookup:
CREATE INDEX ON :User(username)
CREATE INDEX ON :Role(name)
To create relationships you might use:
MATCH (u:User {username:'admin'}), (r:Role {name:'ROLE_WEB_USER'})
CREATE (u)-[:HAS_ROLE]->(r)
The MATCH will use an index if possible. If there is no index, it will lookup up all nodes carrying the label and see if the property matches.
N.B. the syntax above will only work with Neo4j 2.0.0-RC1 and above.
Update as of 4/2020:
The new Cypher syntax is as follows. as 'CREATE INDEX ON' has been deprecated is..
CREATE INDEX FOR (n:Label) ON (n.property)

Resources