Neo4j 第五篇:批量更新数据

摘要:
与图形数据的查询相比,Neo4j更新图形数据的速度较慢。通常,Neo4j更新数据的工作流程是:每次数据更新都会执行一个数据库连接,打开一个事务,并更新事务中的数据。当Cypher语句的结构相同时,Neo4j数据库直接重用缓存中生成的执行计划,而无需重新生成,这也可以提高查询性能。除了官方的Neo4jDriver,本文还分享了Neo4j客户端用于批量更新图形数据。Neo4jClient提供了更强大的功能,并支持参数和批量更新操作。

相比图形数据的查询,Neo4j更新图形数据的速度较慢,通常情况下,Neo4j更新数据的工作流程是:每次数据更新都会执行一次数据库连接,打开一个事务,在事务中更新数据。当数据量非常大时,这种做法非常耗时,大多数时间耗费在连接数据库和打开事务上,高效的做法是利用Neo4j提供的参数(Parameter)机制和UNWIND子句:在一次数据更新中,进行一次连接,打开一次事务,批量更新数据;参数用于提供列表格式的数据,UNWIND子句是把列表数据展开成一行一行的数据,每行数据都会执行结构相同的Cypher语句。再批量更新图形数据之前,用户必须构造结构固定的、参数化的Cypher语句。当Cypher语句的结构相同时,Neo4j数据库直接从缓存中复用已生成的执行计划,而不需要重新生成,这也能够提高查询性能。

除了官方的Neo4j Driver之外,本文分享使用Neo4jClient对图形数据批量更新,Neo4jClient提供的功能更强大,并支持参数和批量更新操作。

我的Neo4j系列的文章收录在:Neo4j

一,参数和UNWIND子句

1,通过RESTful API传递参数

Neo4j提供HTTP API处理Cypher语句和参数,在示例代码中,Neo4j的参数通过HTTP请求传递,statement定义的是查询语句,parameters定义的是参数。

在批量更新数据时,没有必要发送多个HTTP请求,通过参数,可以在一个HTTP请求(Request)中,开始一个事务,在事务中执行Cypher语句批量更新数据,最后提交该事务。

在发送HTTP请求传递参数批量更新数据时,设置HTTP Request的参数如下:

POST http://localhost:7474/db/data/transaction/commit
Accept: application/json; charset=UTF-8
Content-Type: application/json

注意:在HTTP API中,引用参数的格式是:{param}。

复制代码
{
  "statements" : [ {
    "statement" : "CREATE (n {props}) RETURN n",
    "parameters" : {
      "props" : {
        "name" : "My Node"
      }
    }
  } ]
}
复制代码

2,展开(UNWIND)子句

UNWIND子句把列表式的数据展开成一行一行的数据,每一个行都包含更新所需要的全部信息,列表式的数据,可以通过参数来传递。

例如,定义参数events,该参数是一个JSON字符串,键events是参数名,其值是一个数组,包含两个数组元素。

{
  "events" : [ {  "year" : 2014, "id" : 1}, {"year" : 2014, "id" : 2 } ]
}   

通过$events引用参数,UNWIND子句把events数组中的两个元素展开,每个元素执行一次Cypher语句,由于Cypher的语句结构固定,因此,执行计划被缓存起来,在执行数据更新任务时,参数被UNWIND子句展开,复用执行计划,提高数据更新的速度。

UNWIND $events AS event
MERGE (y:Year { year: event.year })
MERGE (y)<-[:IN]-(e:Event { id: event.id })
RETURN e.id AS x
ORDER BY x

二,在Neo4j Browser中使用参数

Neo4j Browser是Neo4j内置的浏览器,用于管理数据库,更新数据库和查询数据,再命令窗体中,通过“:”能够引用内置的命令,例如,通过 ":param"能够定义参数,并能够在下一个Cypher语句中引用参数。

1,通过:param命令定义参数

在Neo4j Browser中,输入第一个命令,通过:param 命令定义参数,

Neo4j 第五篇:批量更新数据第3张

2,通过$param引用参数

紧接着,输入Cypher语句,通过$param引用参数

Neo4j 第五篇:批量更新数据第4张

3,查看创建的图形

参数是一个列表格式的数据,在参数events中,两个event的year属性都是2014,因此,MERGE子句只会创建一个Year节点;由于两个event的id属性不同,因此MERGE子句会创建两个Event节点,并创建Year节点和Event节点之间的关系,图形如下图:

Neo4j 第五篇:批量更新数据第5张

三,使用Neo4jClient批量更新数据

在工程(Projects)中输入命令安装Neo4jClient,

Package-Install Neo4jClient

1,连接Neo4j数据库

创建客户端,连接到数据库,创建的Uri的格式是:http://host_name:7474/db/data,并输入用户名和密码,然后创建图形客户端,并连接到Neo4j数据库。

复制代码
private GraphClient _client;
public Neo4jClientProvider()
{
    _client = new GraphClient(new Uri("http://localhost:7474/db/data"), "user_name", "password");
    _client.Connect();
}
复制代码

2,批量创建节点

传递List<T>参数,通过Unwind函数引用List,并为参数命名为"ns",在Cypher语句中引用参数"ns"

复制代码
public void CreateNodes(List<DataModel> nodes)
{
    _client.Cypher
        .Unwind(nodes, "ns")
        .Create("(n:NodeLable)")
        .Set("n.NodeID=ns.NodeID")
        .Set("n.Name=ns.Name")
        .ExecuteWithoutResults();
}
复制代码

2,批量创建关系

在List<T>参数中,传递两个节点的映射,在Neo4j数据库中,关系必须具有类型,因此,在把参数传递到Neo4j数据中时,需要确定两个节点和关系类型,以创建关系

复制代码
public bool CreateRelationships(List<RelationshipModel> nodes)
{
    _client.Cypher
        .Unwind(nodes, "ns")
        .Match("(n:Lable1),(s:Lable2)")
        .Where("n.NodeID=ns.NodeID and s.NodeID=ns.RelatedID")
        .Merge("(n)-[r:RelationshipType]->(s)")
        .ExecuteWithoutResults();
}
复制代码

参考文档:

3.3.6. UNWIND

Getting Started with Neo4j in .NET with Neo4jClient Library

Batch insert nodes and relations neo4jclient

5 Tips & Tricks for Fast Batched Updates of Graph Structures with Neo4j and Cypher

关于Neo4j和Cypher批量更新和批量插入优化的5个建议

免责声明:文章转载自《Neo4j 第五篇:批量更新数据》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇.NetCore快速上手Consul,留给自己一点思考的空间Flowable源码分析:Spring Data JPA实现从自己创建的数据库中读取指定信息下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

vue+ts+router实现单页面打开新窗口,不显示侧边栏问题(返回上一页,保留数据)

1. 单页面点击打开详情页为新窗口打开    const param :any ={ id:row.RELIC_INFO_ID, categoryCode : row.CATEGORYID, classCode : row.CLASSID, reliCode:row.RELICCODE,}; 把普通的路由跳转方式: this.$router.pu...

linux执行命令并获取结果(system)

执行系统命令,并返回输出的结果 首先需要了解mkstemp(): mkstemp()函数在系统中以唯一的文件名创建一个文件并打开,而且只有当前用户才能访问这个临时文件,并进行读、写操作。   mkstemp函数在系统中以唯一的文件名创建一个文件并打开,而且只有当前用户才能访问这个临时文件,并进行读、写操作。 mkstemp函数只有一个参数,这个参数是个...

axios基础及请求传参

axios基础使用及组件传参 Axios是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中 参考官方文档:https://github.com/axios/axios 1、安装 //使用npm npm install axios --save //使用yarn yarn add axios 2、引用 Vue-cli 中单个...

客户端(springmvc)调用netty构建的nio服务端,获得响应后返回页面(同步响应)

后面考虑通过netty做一个真正意义的简约版RPC框架,今天先尝试通过正常调用逻辑调用netty构建的nio服务端并同步获得返回信息。为后面做铺垫 服务端实现 我们先完成服务端的逻辑,逻辑很简单,把客户端请求的内容加上服务器时间戳一并返回 public void run() throws InterruptedException { Ev...

Neo4j社区版配置文件

#*****************************************************************# Neo4j configuration## For more details and a complete list of settings, please see# https://neo4j.com/docs/oper...

PHP curl请求封装

/** * @Description: curl请求 * @Author: Yang * @param $url * @param null $data * @param string $method * @param array $header * @param bool $https * @param int $timeout * @...