Neo4J - Creating Relationship on existing nodes - neo4j

I am new to Neo4J and I am looking to create a new relationship between an existing node and a new node.
I have a university node, and person node.
I am trying to assign a new person to an existing university.
I am trying to following code:
MATCH (p:Person {name:'Nick'}), (u:University {title:'Exeter'}) CREATE (p)-[:LIKES]->(u)
So in the above code: MATCH (p:Person {name:'Nick'}) is the new user
AND (u:University {title:'Exeter'}) is the exisiting univeristy.
But it is coming back (no changes, no rows)
I have even tried the query without the MATCH part but no luck either.
I have looked at few similar answers but they didn't seem to work either.
Any help would be very much appreciated. Thank you.

Match before u create new one, as suggested in the comments!
MATCH(u:University {title:'Exeter'})
CREATE(p:Person {name:'Nick'})
CREATE(p)-[w:LIKES]->(u)
return w

You could also use a MERGE statement as per the docs:
MERGE either matches existing nodes and binds them, or it creates new data and binds that. It’s like a combination of MATCH and CREATE that additionally allows you to specify what happens if the data was matched or created.
You would do a query like
MERGE (p:Person {name:'Nick'})-[:LIKES]->(u:University {title:'Exeter'})

It is because when you match you search for a nodes in your db. The db says i can't make the realtion "when the nodes dont exist".
Luckily there is something called merge it is like a match +create when he does not find the whole path he creates it.
it should be something like merge 'node1' merge'node2' create(node1)[]->(node2)

Related

neo4j relationships between nodes using a common property (id) without creating more nodes

I have been trying to match together two different nodes (process) and (process framework) that have the same id. I want to set a relationship between those (called:SAME).
The query works but it creates 3 times the amount of processes that I wanted and I can´t figure out why:
MATCH (p:Process)
MATCH (pcf:ProcessFramework)
WHERE HAS (p.id) AND HAS (pcf.pcf_id) AND p.id=pcf.pcf_id
MERGE (p)<-[:same]-(pf)
return p,pcf
I also tried it with CREATE UNIQUE instead of MERGE but its the same result. I am not a developer so maybe I am doing a very obvious mistake but I really can´t see it!
Thanks!
You have a typo in your query, you use pf where you should use pcf in the MERGE.
I'd also change it to this and make sure you have an index on :ProcessFramework(pcf_id)
MATCH (p:Process)
MATCH (pcf:ProcessFramework)
WHERE p.id=pcf.pcf_id
MERGE (p)<-[:same]-(pcf)
return p,pcf

Cypher: Create relationships between nodes based on a common property key id

I'm brand new to Cypher (and Stackoverflow) and am having trouble creating relationships between nodes based on share property keys.
I would like to do something like this:
MATCH (a:Person)-->()<--(b:Country)
WHERE HAS (a.id) AND HAS (b.id) AND a.id=b.id
CREATE (a)-[:LIVES]->(b);
to create a relationship between Country node and Person nodes where they share the same id.
The above creates no errors when run but doesn't create any relationships either and I know that the ids should match.
Many thanks!!
EDIT:
I think I know what is going wrong - I'm asking to match nodes that have a relationship to eachother but no relationships are set up yet hence 0 results. I have now tried:
MATCH (a:Person),
(b:Country)
WHERE HAS (a.id) AND HAS (b.id) AND a.id=b.id
CREATE (a)-[:LIVES]->(b);
and the query is running. It's a big data set so might take a while......
That worked. Had to reduce the size of my data set (down from 64k nodes) as Neo4j was taking way too long to process but once I had a smaller set it worked fine.
One minor addition for future Googlers.
per the help files as of version 3.4
The has() function has been superseded by exists() and has been removed.
The new code should read
MATCH (a:Person),
(b:Country)
WHERE EXISTS (a.id) AND EXISTS (b.id) AND a.id=b.id
CREATE (a)-[:LIVES]->(b);

CREATE UNIQUE in Neo4j not working?

I currently have a graph database that tries to model geographical data.
For the sake of simplicity, one of the relationships I'm using is (Object)-[:IS_IN]-(Object) to relate entities (for example place1 is in city1).
Right now I'm trying to add certain places to the DB, while trying to preserve any kind of already existing nodes. So if for example I already have a relationship such as (place1)-[:is_in]->(city1) and then try to add a (place2)-[is_in]->(city1) relationship, it should link place 2 back to the existing city1 node instead of creating a new one with the same name. So I tried using CREATE UNIQUE like this:
MATCH (obj:Object {name: 'place2'}) CREATE UNIQUE (obj)-[:IS_IN]->(city:Object {name: 'city1' })
However, this keeps creating new nodes named city1. What gives? Should I be using MERGE instead?
Use
MATCH (obj:Object {name: 'place2'}), (city:Object {name: 'city1' } CREATE UNIQUE (obj)-[:IS_IN]->(city)
instead.
I came across the same problem and found this solution that works fine for me :
MERGE (obj:Object {name: 'place2'}) MERGE (city:Object {name: 'city1' }) CREATE UNIQUE (obj)-[:IS_IN]->(city)
What this does (as I understand it) : Finds 'place2' node or creates it if it doesn't exist, finds 'city1' node or creates it if it doesn't exist, creates a :IS_IN relationship if it doesn't exist.
So, whatever the initial situation is, you end up with the complete pattern, but no node or relationship dupl.
I tested it with various starting situations and it worked as expected.
Note that I'm a Neo4j and cypher beginner, this may not be the best solution.
The question is old, I answered it anyway because other people may find it useful.

How to create a new relationship in Neo4j, starting from an existing one, using a Cypher query?

Is there a simple way to create a new relationship in Neo4j, starting from an existing one?
Starting from the actor-director-movie database used in the tutorials, what I would like to do is to get all the {(actor1),(actor2)} couples of nodes in the graph satisfying the relationships:
(actor1)-[:ACTED_IN]->(movie)<-[:ACTED_IN]-(actor2)
and use them to create a new relationship like:
(actor1)-[:ACTED_IN_THE_SAME_MOVIE_AS]-(actor2)
in whatever direction (I am interested in both directed and undirected graphs).
Is there a way to do this with a simple Cypher query?
Many thanks,
sTe
Using the sample movie dataset:
MATCH (actor1:Person)-[:ACTED_IN]->(:Movie)<-[:ACTED_IN]-(actor2:Person)
WITH actor1, actor2
MERGE (actor1)-[:ACTED_IN_THE_SAME_MOVIE_AS]-(actor2)
I'd do that :
MATCH (actor1)-[:ACTED_IN]->()<-[:ACTED_IN]-(actor2)
CREATE UNIQUE (actor1)-[:ACTED_IN_THE_SAME_MOVIE_AS]-(actor2)
which is basically what you said. Relations are uni-directional (no way around), but the api (Cypher queries or Traversal) can read them both ways (so it doesn't really matter which way your create them in some cases).
To check if what you did is ok, you can run the following :
MATCH (actor1)-[:ACTED_IN_SAME_MOVIE]-(actor2)
RETURN actor1, actor2

how to create unique relationships neo4j 2.0

I am trying to create some unique relationships between entities in neo4j. Right now I have authors and articles, with a Authored relationship between them. I want to create a CoAuthored relationship between the entities
Like so
match (a)-[r]->(b)<-[r2]-(c)
create (a)-[new:CoAuthor]->(c)
However, I would like to create a unique co-author relationship, but update the weight if it already exists. I saw this postm but the syntax is no longer supported In Cypher, how can I create a relationship if it doesn't exist; update property if it does
SyntaxException: This syntax is no longer supported (missing properties are now returned as null). Please use (not(has(<ident>.weight)) OR <ident>.weight=<value>) if you really need the old behavior.
I do not quite understand what it is that I am replacing. I looked at the Merge command, but can't quite get it to work
You should be able to replace create with merge in this particular case.
match (a)-[r]->(b)<-[r2]-(c)
merge (a)-[new:CoAuthor]->(c)
on create set new.weight=1
on match set new.weight=new.weight+1

Resources