如何批量插入关系

Dav*_*vid 2 neo4j cypher

我正在玩Neo4j.我有一个包含大约400,000个节点的数据库.我想从CSV文件中插入关系.大约有140万个关系.

我目前正在使用REST API.REST请求如下所示:

POST http://localhost:7474/db/data/cypher
Accept: application/json; charset=UTF-8
Content-Type: application/json
{"query": "MATCH (a { ConceptId: '280844000' }), (b { ConceptId: '71737002' }) CREATE (a)-[:Is_a]->(b) RETURN a"}
Run Code Online (Sandbox Code Playgroud)

问题是每个请求都需要几秒钟.这对于我希望插入的关系数量来说太慢了.

我无法访问底层节点ID,只有我插入它时给出的属性.

有更快的方法吗?

注意:我目前没有使用索引(我还没有弄清楚如何添加它们),但明天会再次使用索引.我只是想知道是否有某种方式以批量方式插入关系.

jja*_*erg 8

第一个改进可能是为节点分配标签,以便您可以使用索引.如果没有索引conceptId,则每次执行查询时,它将扫描400,000个节点两次,对于您匹配的两个节点中的每个节点扫描一次.根据您的查询进行推测,您可以为节点提供标签:Concept并为conceptId属性编制索引,如下所示

MATCH (n)
// WHERE HAS (n.conceptId) //if you have some nodes that don't represent concepts, and conceptId distinguishes the ones that do from others
SET n:Concept
Run Code Online (Sandbox Code Playgroud)

然后为索引

CREATE INDEX ON :Concept(conceptId)
Run Code Online (Sandbox Code Playgroud)

或者如果conceptId是唯一标识值,则可以使用约束

CREATE CONSTRAINT ON (c:Concept) ASSERT c.conceptId IS UNIQUE
Run Code Online (Sandbox Code Playgroud)

设置标签并创建索引后,可以使用它们快速查找要连接的节点.您需要做的就是在查询中包含label和indexed属性.您已经使用了索引属性,因此添加了查询所成的标签

MATCH (a:Concept {ConceptId: '280844000'}), (b:Concept {ConceptId: '71737002'}) 
CREATE (a)-[:Is_a]->(b) 
RETURN a
Run Code Online (Sandbox Code Playgroud)

您可以在Neo4j文档中阅读有关模式的更多信息.

第二个改进可能是使用LOAD CSV@stephenmuss建议.

如果您将来的查询不是基于csv文件,则还有两件事需要考虑.第一个是参数化您的查询.你的HTTP电话会看起来像这样

POST http://localhost:7474/db/data/cypher
Accept: application/json; charset=UTF-8
Content-Type: application/json
{"query": "MATCH (a { ConceptId: {a} }), (b { ConceptId: {b} }) CREATE (a)-[:Is_a]->(b) RETURN a","params":{"a":"280844000","b":"71737002"}}
Run Code Online (Sandbox Code Playgroud)

这允许执行引擎为该结构的第一个查询创建一次执行计划.下次发出具有相同结构的查询时,将重用缓存的执行计划.这将显着提高具有相同结构的重复查询的性能.

最后的事情是@ulkas评论,以批量插入.一个原因LOAD CSV是更快的是它在一个事务中执行多个操作.您可以使用事务性密码端点执行类似操作.然后,您可以为每个事务执行几千个小语句,这对于在数据库上操作的性能要高得多,并且还将减少线路上的开销.为事务端点设计有效负载以及处理异常稍微复杂一些.下面是一个简单的例子,您可以在Neo4j手册页中阅读更多相关内容.

POST http://localhost:7474/db/data/transaction
Accept: application/json; charset=UTF-8
Content-Type: application/json
{"statements":[
    {"statement":"MATCH (a:Concept {ConceptId: {a}}), (b:Concept {ConceptId: {b}}) CREATE (a)-[:Is_a]->(b) RETURN a","parameters":{"a":"280844000","b":"71737002"}},
    {"statement":"MATCH (a:Concept {ConceptId: {a}}), (b:Concept {ConceptId: {b}}) CREATE (a)-[:Is_a]->(b) RETURN a","parameters":{"a":"199401294","b":"51233509"}}
]}
Run Code Online (Sandbox Code Playgroud)

例如,服务器返回location新事务"http://localhost:7474/db/data/transaction/1".您可以继续在同一事务中执行语句

POST http://localhost:7474/db/data/transaction/1
Accept: application/json; charset=UTF-8
Content-Type: application/json
{"statements":[...]}
Run Code Online (Sandbox Code Playgroud)

当你完成了你提交.提交调用也可以包含语句.

POST http://localhost:7474/db/data/transaction/1/commit
Accept: application/json; charset=UTF-8
Content-Type: application/json
{"statements":[...]}
Run Code Online (Sandbox Code Playgroud)

  • 这是一种让你再次相信StackOverflow任务的帖子. (2认同)