简体   繁体   中英

Neo4j - Create relationship between nodes based on property

I have nodes in a graph. The nodes are of two types; lets call them group a and group b . I own a mapping of relationships between nodes in group a and group b , which are based on a name property in each node. For clarity, the mapping file looks somewhat like this:

(:a {name:'abc'})-[:RELATES_TO]->(:b {name:'def'}),
(:a {name:'abd'})-[:RELATES_TO]->(:b {name:'def'}),
...
(:a {name:'uvw'})-[:RELATES_TO]->(:b {name:'xyz'})

The name between groups is not shared, so I cannot use something like:

MATCH (a),(b)
WHERE a.name = b.name
MERGE (a)-[:RELATES_TO]->(b)

Since the existing nodes contain multiple properties, but the mapping only contains the name property, using the following MERGE results in the generation of new nodes, rather than the connecting of my existing nodes:

MERGE
(:a {name:'abc'})-[:RELATES_TO]->(:b {name:'def'}),
(:a {name:'abd'})-[:RELATES_TO]->(:b {name:'def'}),
...
(:a {name:'uvw'})-[:RELATES_TO]->(:b {name:'xyz'})

I believe could implement each relationship individually by manually adding the all properties to the mapping file and running the above merge, but I believe that all of the information to add the relationships already exists; I have both the start point and end point for each relationship. As a result, I suspect there must be a more elegant way to solve this problem.

It's been fairly ubiquitous in my past experience w/ Neo4j that the above problem occurs -> It's unclear to me whether I'm missing some syntax knowledge and this is an easy fix, or if I'm abusing the way Neo4j is intended to operate, and I need rethink how I'm proceeding.

The problem may be caused by the fact that you MERGE the entire pattern, which will cause the entire pattern to be created. Assuming that the name properties serve as a unique key, I suggest you try this:

// make sure you have a list of a,b combinations, resulting from previous processing
a,b
'abc','def'
'abd','def'
...
'uvw','xyz''

// process these combinations
WITH a,b
MERGE (a:a {name:a})
MERGE (b:b {name:b})
MERGE (a)-[:RELATES_TO]->(b)

Note that creating a CONSTRAINT on the name property will sspeed things up

First - create the nodes:

create
(:a {name:'abc'}),
(:a {name:'abd'}),
(:a {name:'uvw'}),
(:b {name:'def'}),
(:b {name:'def'}),
(:b {name:'xyz'})

Second - Enable Multi Statement Editor

Navigate to settings. Add check to Enable multi statement query editor

Third - Create Match/Merge Pairs for Each Relationship

The semicolon represents the end of a query. This is how you take advantage of the multi statement query editor.

match(a:a {name:'abc'}),(b:b {name:'def'})
merge(a)-[:RELATES_TO]->(b);
match(a:a {name:'abd'}),(b:b {name:'def'})
merge(a)-[:RELATES_TO]->(b);
match(a:a {name:'uvw'}),(b:b {name:'xyz'})
merge(a)-[:RELATES_TO]->(b);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM