0

我从 SQL Server 将两个名为 Keys 和 Acc 表的表导出为 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 属性是唯一的,我在从 sql server 导出时将一个五个字符的前缀连接到 IdKey 以标识应用程序的对象,因为我们无法根据手册中学到的多个字段创建索引。现在我的目标是构建应用程序之间的关系。例如:

  • Node1是Application1的源代码对象
  • Node2是Application1的另一个源代码对象
  • Node3是Application2的源代码对象

由于 Acc 中的记录已经导入,因此已经创建了从 Node1 到 Node2 的 CALL 关系。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)
4

1 回答 1

0

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

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

于 2016-04-14T18:06:54.970 回答