I am just starting out with neo4j and cypher. I am building a database to store names and synonyms for different chemicals. The way I currently do this is something like this:
CREATE CONSTRAINT ON (flow:Flow) ASSERT flow.name IS UNIQUE;
CREATE (a:Flow {name: "Ethene"})-[:synonym]->(b:Flow {name: "Ethylene"});
(The -->
syntax is required by cypher syntax even though synonym is a bidirectional relationship).
Now-- say I want to add a new flow which is a synonym to both,
CREATE (c:Flow {name: "C2H4"})-[:synonym]->(b:Flow {name: "Ethylene"})
After that, I will have 3 nodes in a linear relationship (a)-[:synonym]->(b)<-[:synonym]-(c)
. But synonymy is transitive, so the graph of synonyms should really be complete (the a-[:synonym]-c
relationship is missing)
Is there a way to automatically create a :synonym
relationship to a node and all that node's synonyms?
The following seems to work, except it feels clumsy and also is not idempotent (if it's run again, it creates a c-->c
relationship):
// create a new synonym to 'Ethylene' with the name 'C2H04'
MATCH (j:Flow {name:"Ethylene"})-[:synonym]-(k)
WITH j,k
MERGE (c:Flow {name:"C2H04"})-[:synonym]->(j)
MERGE (c)-[:synonym]->(k)
Is there a better way to create these relationships? Alternately, is there a way to collapse all the synonym relationships so that a query will return all synonyms of a node even if they are not directly connected?