Question

With a graph that contains nodes with a free text property, I would like to identify nodes matching a specific regular expression, create a new annotation node and link matched nodes to the annotation one. I tried with MERGE and CREATE UNIQUE, however in both attempts several identical annotation nodes are created. I'd be very grateful if one could help me putting together the proper cypher command. Below are some code I tried:

MATCH (p:Paper), (a:Annotation {Keyword: 'cool'}) 
WHERE p.Title =~ ".*cool.*" 
CREATE UNIQUE (p)-[:isRelatedTo]->(a);

or

MATCH (p:Paper) WHERE p.Title =~ ".*cool.*" 
CREATE UNIQUE (p)-[:isRelatedTo]->(a:Annotation {Keyword: 'cool'});

or

MATCH (p:Paper) WHERE p.Title =~ ".*cool.*" 
MERGE (p)-[:isRelatedTo]->(a:Annotation {Keyword: 'cool'});

Thanks in advance, Pierre.

Was it helpful?

Solution

Your final approach (in your comments) has these drawbacks:

  1. It only works if the appropriate Annotation node already exists.
  2. You are hardcoding the "cool" string in 2 places. I presume what you really want is to be able to do the same thing with any string.

EDITED

The following modified query should solve both of the above issues, efficiently, and also creates the Annotation node if necessary.

  1. It uses MERGE to: create the Annotation if and only if it does not already exist.
  2. It uses CREATE UNIQUE to create the isRelatedTo relationship if it does not already exist.
  3. It allows you to specify a term parameter for the string that you want to filter for (and use as the Keyword for the Annotation). Passing the string as a parameter can make your query much faster.
MATCH (p:Paper) WHERE p.Title =~ (".*" + {term} + ".*")
MERGE (a:Annotation {Keyword: {term}})
CREATE UNIQUE (p)-[:isRelatedTo]->(a)
RETURN p, a;

Go to this console to test this (without the term parameter).

OTHER TIPS

Answering to my self, above ideas were pretty close to a working solution, only missing a WITH statement.

MATCH (p:Paper) WHERE p.Title =~ ".*cool.*" 
MERGE (a:Annotation {Keyword: "cool"}) 
WITH a, p merge (a) <-[:isRelatedTo]- (p) 
RETURN p

This query creates the :Annotation node if necessary and link :Paper nodes that match the regular expression to it.

Thank you all for helping.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top