2016-04-14 74 views
0

我从SQL Server中导出了两个名为Keys和Acc表的CSV表格作为CSV文件,并使用以下命令将它们成功导入到Neo4J。根据条件克隆一些关系

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代表源代码对象,Acc代表它们之间的关系。我为三个不同的应用程序项目导入了这两个表格三次。因此,为了保持IdKey属性对于三个应用程序是唯一的,我将一个五个字符的前缀与IdKey连接起来,以便在从sql server导出时标识应用程序对象,因为我无法像从手册中学到的那样根据多个字段创建索引。现在我的目标是构建应用程序之间的关系。例如:

  • 节点1是应用1
  • 节点2的源代码的对象是应用程序1的另一个源代码对象
  • 节点3是应用2的源代码的对象

已经有一个CALL由于已导入的Acc中的记录,从节点1创建到节点2的关系。 Node2的名称等于Node3的名称。所以我们可以说Node2和Node3实际上是相同的源代码。所以我们应该创建一个从Node1到Node3的关系。为了实现它,我在下面写了一个命令。但我想确定它是正确的。因为我不知道它会执行多久。

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

回答

0

这下面的查询应该是有效的,假设你也create an index: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不会使用索引。因此,此查询将每个caller的所有called名称放入names集合中,然后在calledNew.KeyNam与该集合中的项目之间进行比较。这会导致索引被使用,并会加速识别潜在的重复被叫节点。

此查询还执行NOT (caller)-[:CALLS]->(calledNew)检查,以避免在相同节点之间创建重复关系。