相比图形数据的查询,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的参数如下:

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

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

  1. {
  2. "statements" : [ {
  3. "statement" : "CREATE (n {props}) RETURN n",
  4. "parameters" : {
  5. "props" : {
  6. "name" : "My Node"
  7. }
  8. }
  9. } ]
  10. }

2,展开(UNWIND)子句

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

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

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

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

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

二,在Neo4j Browser中使用参数

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

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

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

2,通过$param引用参数

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

3,查看创建的图形

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

三,使用Neo4jClient批量更新数据

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

  1. Package-Install Neo4jClient

1,连接Neo4j数据库

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

  1. private GraphClient _client;
  2. public Neo4jClientProvider()
  3. {
  4. _client = new GraphClient(new Uri("http://localhost:7474/db/data"), "user_name", "password");
  5. _client.Connect();
  6. }

2,批量创建节点

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

  1. public void CreateNodes(List<DataModel> nodes)
  2. {
  3. _client.Cypher
  4. .Unwind(nodes, "ns")
  5. .Create("(n:NodeLable)")
  6. .Set("n.NodeID=ns.NodeID")
  7. .Set("n.Name=ns.Name")
  8. .ExecuteWithoutResults();
  9. }

2,批量创建关系

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

  1. public bool CreateRelationships(List<RelationshipModel> nodes)
  2. {
  3. _client.Cypher
  4. .Unwind(nodes, "ns")
  5. .Match("(n:Lable1),(s:Lable2)")
  6. .Where("n.NodeID=ns.NodeID and s.NodeID=ns.RelatedID")
  7. .Merge("(n)-[r:RelationshipType]->(s)")
  8. .ExecuteWithoutResults();
  9. }

参考文档:

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 第五篇:批量更新数据的更多相关文章

  1. Neo4j 第十篇:更新数据

    更新图包括图的节点和关系的创建.更新和删除,也能更新图的节点和关系的属性.节点标签和关系类型. 一,创建节点 1,创建空的节点 CREATE (n) CREATE (a),(b) 2,创建带标签的节点 ...

  2. FreeSql (十四)批量更新数据

    FreeSql支持丰富的更新数据方法,支持单条或批量更新,在特定的数据库执行还可以返回更新后的记录值. var connstr = "Data Source=127.0.0.1;Port=3 ...

  3. 批量更新数据小心SQL触发器的陷阱

    批量更新数据时候,Inserted和Deleted临时表也是批量的,但触发器只会调用执行一次!两个概念千万不要弄混淆! 错误的理解:例如:创建在A表上创建了一个Update触发器,里面写的是Updat ...

  4. SQL批量更新数据

    SQL批量更新数据 step1:导入Excel数据, 具体见百度.注意点:一列中含有float型数据和文本数据的时候,导入要将Excel中的表格属性改成文本,或在数字项目前加个单引号.   step2 ...

  5. mybatis学习之路----批量更新数据两种方法效率对比

    原文:https://blog.csdn.net/xu1916659422/article/details/77971696/ 上节探讨了批量新增数据,这节探讨批量更新数据两种写法的效率问题. 实现方 ...

  6. mysql 常用命令,连接数据库,查看建表语句,批量导入数据,批量更新数据,连接查询

    1. 1)MySQL 连接本地数据库,从cmd中进入mysql命令编辑器: root root分别为用户名和密码 mysql -uroot -proot 2)MySQL 连接本地数据库,用户名为“ro ...

  7. mysql下的将多个字段名的值复制到另一个字段名中(批量更新数据)字符串拼接cancat实战例子

    mysql下的将多个字段名的值复制到另一个字段名中(批量更新数据)mysql字符串拼接cancat实战例子: mysql update set 多个字段相加,如果是数字相加可以直接用+号(注:hund ...

  8. 批量更新数据(BatchUpdate)

    批量更新数据(BatchUpdate) /// <summary> /// 批量更新数据,注意:如果有timestamp列,要移除 /// </summary> /// < ...

  9. SqlServer 利用游标批量更新数据

    SqlServer 利用游标批量更新数据 Intro 游标在有时候会很有用,在更新一部分不多的数据时,可以很方便的更新数据,不需要再写一个小工具来做了,直接写 SQL 就可以了 Sample 下面来看 ...

随机推荐

  1. PHPCMS笔记第二弹

    熟练地使用PHPCMS可以插入模板,将静态站转变为动态站也更加方便,多加练习还是有好处的 将index.html的头和尾拆分出来,分别放在header.html和footer.html文件夹中,这三个 ...

  2. 如何修改Xampp服务器上的mysql密码

    今天自己在搞php的过程中发现,如果我们使用Xampp服务器自带数据库mysql,就必须先修改mysql的密码,大家都知道,mysql的初始面为空,但是如果连接数据库是密码为空就会报错,在网上查找了很 ...

  3. WebForm捆绑压缩js和css(WebForm Bundling and Minification)

    .net framework 4以上,可以使用Microsoft.AspNet.Web.Optimization 新建4.0项目 Nuget搜索optimization,安装第一个包 加入Bundle ...

  4. JQuery处理DOM元素-属性操作

    JQuery处理DOM元素-属性操作 //操作元素的属性: $('*').each(function(n){ this.id = this.tagName + n; }) //获取属性值: $('') ...

  5. JS取消浏览器文本选中的方法

    一 .问题的出现 今天在使用Easy-UI 的messager.alert()方法时候出现浏览器文本被选中,不知道其中是什么原因,如下图所示. 二 .解决思路 我最后的思路时在弹出消息框的同时,取消浏 ...

  6. 五子棋AI大战OC实现

    Gobang 五子棋AI大战,该项目主要用到MVC框架,用算法搭建AI实现进攻或防守 一.项目介绍 1.地址: github地址:Gobang 2.效果图: 二.思路介绍 大概说下思路,具体看代码实现 ...

  7. 设备offline时如何自动重置

    在linux底层 Linux/include/uapi/linux/usbdevice_fs.h中,重置_IO('U', 20)可以重置usb设备. 因此,我们可以在脚本中利用这个方法去重置USB 代 ...

  8. JS理解之闭包

    首先,闭包是什么?这个问题,百度上一大堆,然后我也是,现在学的有点累,来回顾一下吧算是,懂的自动略过,小弟不才,道行入不了你们法眼. 我认为的闭包是,就是取到,不是在自己作用域内或者按照js的规则,娶 ...

  9. (练习题)利用构造器函数实现三个小实例——不使用String()与Array()构造器和Math对象,不使用内建的方法的方法和属性。

    1)在String()构造器不存在的情况下自定义一个myString()构造器函数.由于String()不存在,因此您在写构造器函数时不能使用任何属于内建String对象的方法和属性.并让你所创建的对 ...

  10. (知识点)JavaScript闭包

    下面是我对闭包的理解:(把他们整理出来,整理的过程也是在梳理) 1.首先,在理解闭包之前: 我们首先应该清楚下作用域和作用域链 作用域:每个函数定义时创建时自己的环境即作用域 作用域链:函数内可访问自 ...