I am using the MATCH and MERGE operation in Neo4j in order to avoid duplicate relationships. My program does the following: whenever two nodes are "close", it creates a relationship from node A to B and vice-versa. I only want one of those relations, and it is hard to control this in the program so I am using the database instead.
Imagine that nodes 3 and 81 are related to each other. If I run
OPTIONAL MATCH (n:Node {id:3}), (m:Node {id:81})
MERGE (n)-[r:REL {relT: "SOR" , simT:2205}]->(m)
twice from the console, the second query doesn't do anything, which is the expected behavior. However, when I use neo4j-client to log these relations (it sends the query twice, as explained), two relations are created. I think that this has nothing to do with the client I am using, as the MERGE is obviously interpreted by neo4j. I have checked if relationship properties created are equal or not, but they seem to be the same (first and last row in the table):
Anyone can give me any hint on how to troubleshoot this?
EDIT: The code I am using in my C code is:
std::vector<neo4j_map_entry_t> vParams =
{ node1Id, node2Id, relT, simT };
neo4j_result_stream_t *results =
neo4j_run (
connection,
"OPTIONAL MATCH (n:Node {id: {node1Id}}), (m:Node {id: {node2Id}}) MERGE (n)-[r:REL {relT: {relT}, simT: {simT}}]->(m)",
neo4j_map (vParams.data (), vParams.size ()));
which makes me wonder a couple of things... Am I sending a prepared statement? Does MERGE work with prepared statements? As far as I can tell, I am not sending any prepared statement, I am just binding the variables and sending the whole query.
I am not sure if this is the cause of your issue, but if you want to ensure that there is only one instance of a relationship (regardless of the directionality) between 2 nodes, your MERGE
clause should specify a directionless relationship pattern.
For example:
OPTIONAL MATCH (n:Node {id:3}), (m:Node {id:81})
MERGE (n)-[r:REL {relT: "SOR" , simT:2205}]-(m);
Notice that the pattern does not specify a relationship direction. This causes the MERGE
to check for an existing relationship in either direction (instead of in a single direction).