我正在玩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,只有我插入它时给出的属性.
有更快的方法吗?
注意:我目前没有使用索引(我还没有弄清楚如何添加它们),但明天会再次使用索引.我只是想知道是否有某种方式以批量方式插入关系.
第一个改进可能是为节点分配标签,以便您可以使用索引.如果没有索引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)
| 归档时间: |
|
| 查看次数: |
972 次 |
| 最近记录: |