clone some relationships according to a condition

34 Views Asked by At

I exported two tables named Keys and Acc tables as CSV files from SQL Server and imported them successfully to Neo4J by using the commands below.

CREATE INDEX ON :Keys(IdKey) 

USING PERIODIC COMMIT 500
LOAD CSV FROM 'file:///C:/Keys.txt' AS line
MERGE (k:Keys { IdKey: line[0] })
SET k.KeyNam=line[1], k.KeyLib=line[2], k.KeyTyp=line[3], k.KeySubTyp=line[4]

USING PERIODIC COMMIT 500
LOAD CSV FROM 'file:///C:/Acc.txt' AS line
MERGE (callerObject:Keys { IdKey : line[0] })
MERGE (calledObject:Keys { IdKey : line[1] })
MERGE (callerObject)-[rc:CALLS]->(calledObject)
SET rc.AccKnd=line[2], rc.Prop=line[3]

Keys stands for the source code objects, Acc stands for relations among them. I imported these two tables three times for three different application projects. So to maintain IdKey property being unique for three applications, I concatenated a five character prefix to IdKey to identify the Object for Application while exporting from sql server because we can not create index based on multiple fields as I learnt from manuals. Now my aim is constructing the relations among applications. For example:

  • Node1 is a source code object of Application1
  • Node2 is another source code object of Application1
  • Node3 is a source code object of Application2

There is already a CALL relation created from Node1 to Node2 because of the record in Acc already imported. The Name of the Node2 is equal to name of Node3. So we can say that Node2 and Node3 are in fact the same source codes. So we should create a relation from Node1 to Node3. To realize it, I wrote a command below. But I want to be sure that it is correct. Because I do not know how long it will execute.

MATCH (caller:Keys)-[rel:CALLS]->(called:Keys),(calledNew:Keys)
WHERE calledNew.KeyNam = called.KeyNam 
and calledNew.IdKey <> called.IdKey
CREATE (caller)-[:CALLS]->(calledNew)
1

There are 1 best solutions below

0
cybersam On

This following query should be efficient, assuming you also create an index on :Keys(KeyNam).

MATCH (caller:Keys)-[rel:CALLS]->(called:Keys) 
WITH caller, COLLECT(called.KeyNam) AS names 
MATCH (calledNew:Keys) 
WHERE calledNew.KeyNam IN names AND NOT (caller)-[:CALLS]->(calledNew) 
CREATE (caller)-[:CALLS]->(calledNew)

Cypher will not use an index when doing comparisons directly between property values. So this query puts all the called names for each caller into a names collection, and then does a comparison between calledNew.KeyNam and the items in that collection. This causes the index to be used, and will speed up the identification of potential duplicate called nodes.

This query also does a NOT (caller)-[:CALLS]->(calledNew) check, to avoid creating duplicate relationships between the same nodes.