使用MERGE或MATCH将关系插入Neo4j永远运行

时间:2016-06-15 15:39:05

标签: neo4j cypher

我正在使用Locations的简单数据集来试验Neo4j。一个位置可以与另一个关系有关系。 a:位置 - [rel] - b:位置

我已经拥有数据库中的位置(大约700.000+位置条目)

现在我想添加关系数据(170M Edges),但我想首先尝试使用较小的集合的导入逻辑,所以我基本上选择了集合中的2个节点并尝试创建如下关系

MERGE p =(a:Location {locationid: 3616})-[w:WikiLink]->(b:Location {locationid: 467501})
RETURN p;

并且还直接从文档中尝试了这种方法

MATCH (a:Person),(b:Person)
WHERE a.name = 'Node A' AND b.name = 'Node B'
CREATE (a)-[r:RELTYPE { name : a.name + '<->' + b.name }]->(b)
RETURN r

我尝试使用定向合并,非定向合并等。我基本上尝试了上述查询的多个变体,结果是:它们永远运行,即使在15分钟后似乎也没有完成。这很奇怪。

Indexes
  ON :Location(locationid) ONLINE (for uniqueness constraint) 

Constraints
  ON (location:Location) ASSERT location.locationid IS UNIQUE

这就是我目前使用的:

USING PERIODIC COMMIT 1000
LOAD CSV WITH HEADERS FROM 'file:///edgelist.csv' AS line WITH line
MATCH (a:Location {locationid: toInt(line.locationidone)}), (b:Location {locationid: toInt(line.locationidtwo)})
MERGE (a)-[w:WikiLink {weight: toFloat(line.edgeweight)}]-(b)
RETURN COUNT(w);

如果你看一下下面的终端输出,你可以看到Neo4j报告了258ms的查询执行时间,但实际情况有点高于此值。在我看来,这个查询已经花费了几秒钟(这台运行的机器有48GB RAM,16个核心并且相对较新)。 我目前正在使用LIMIT 1000运行此查询(在LIMIT 1之前),但脚本已运行几分钟。我想知道是否必须从MERGE切换到CREATE。问题是,我无法理解EXPLAIN给我的调用图以确定瓶颈。

time /usr/local/neo4j/bin/neo4j-shell -file import-relations.cql 
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| p                                                                                                                                                                                        |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| [Node[758609]{title:"Tehran",locationid:3616,locationlabel:"NIL"},:WikiLink[9422418]{weight:1.2282325516616477E-7},Node[917147]{title:"Khorugh",locationid:467501,locationlabel:"city"}] |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row
Relationships created: 1
Properties set: 1
258 ms

real    0m1.417s
user    0m1.497s
sys 0m0.158s

EXPLAIN of the query

3 个答案:

答案 0 :(得分:0)

如果你没有:

create constraint on loc:Location assert loc.locationid is unique;

然后找到两个节点,并创建相关性。

MATCH (a:Location {locationid: 3616}),(b:Location {locationid: 467501})
MERGE p = (a)-[w:WikiLink]->(b)
RETURN p;

或者如果这些地点尚未存在:

MERGE (a:Location {locationid: 3616})
MERGE (b:Location {locationid: 467501})
MERGE p = (a)-[w:WikiLink]->(b)
RETURN p;

如果从程序中执行此操作,也应使用参数。

答案 1 :(得分:0)

您是否已将Location上的locationid个节点编入索引?

CREATE INDEX ON :Location(locationid)

我遇到类似的问题,在图表中添加边缘并为节点编制索引,导致链接运行速度提高了150倍。

如果节点未编入索引,neo4j将对两个节点进行串行搜索,以便链接在一起。

答案 2 :(得分:0)

USING PERIODIC COMMIT <value>

指定事务中要提交的记录(行)数。由于您的RAM较高,因此最好使用大于100000的值。这样可以减少提交的事务数,并可以进一步减少总时间。