Neo4j入门点滴(一):Cypher

简介:   Cypher,读作(赛佛儿)。名词意为:零,零的记号,或密码索引书;动词含义为计算或用密码书写。不过,更准确的引申要从街舞中借鉴,在街舞中,Cypher就是围圈跳舞,不分先后,没有对手,就是一次一次即兴的到中间去跳。
  Cypher,读作 (赛佛儿 )。名词意为: 零,零的记号,或密码索引书;动词含义为计算或用密码书写。不过,更准确的引申要从街舞中借鉴,在街舞中,Cypher就是围圈跳舞, 不分先后,没有对手,就是一次一次即兴的到中间去跳 在社会网络分析(SNA)中,Neo4j的核心实现形式语言就是功能类似这种围圈舞蹈的Cypher。
  Cypher我理解是一种联系操作语言,之所以将其称为“联系”就是要使之和传统SQL数据库的“关系”相区分。操作对象即图数据库独有的节点(Nodes)、标签(Labels)、联系(Relationships)和属性(Properties)。解释一下,以便理解的更为深入:
  • Node:表征实体,如:人、公司、账户或其他类似的东西。
  • Label:标签不是一开始就有的,后续更新的版本加入了这个功能,极为好用。因为人脑的两种基本认知方式之一就是分类,而标签就是最佳的方法。标签用于标识Node的类别,一个节点可拥有一个或多个标签。标签有助于创建索引,加速检索。
  • Relationship:联系定义了两个Node之间的连接。联系还可以有自己的属性和方向。
  • Property:用于存储Node的相关信息,是Node的内涵定义。属性可以被Node和Relationship拥有,一如Node一样,Property也是一种广泛而基本的存在。
  为了更深入地理解Cypher的语法,需要提前说明一下Cypher查询的执行过程:
  1. 首先,进行语法解析、正确性检查、产生执行计划;
  2. 其次,定位至初始节点;
  3. 再次,选择和遍历联系;
  4. 最后,更改或返回值。
  后续语法的执行基本上都是这四个步骤的不断重复。

一、基本语法(CURD):
1. Create
  试着创建一个Node,这个节点是一个人--顾双双,是我心理咨询的一个来访者,性别女,年龄23。仿照基本格式先写一个:
  1. create (顾双双:患者{gender:"女",age:"23"})
  请注意在下图的结果中,标签是“患者”,节点当前显示的名字是第一个标签的内容“女”:
  当然了,这和我的本意并不相符,我是打算创建姓名为“顾双双”的患者,希望姓名可以在Node中心显示出来。所以,现在CREATE的格式是:create (?:标签名{属性名1:"属性1值", 属性名2:"属性2值"}),所以现在主要的问题是弄清楚“?”代表什么,或者这个部分是否可以省略。
  弄清楚了:?代表的是创建的本实例,正规的一个格式是:
  1. create (n:患者{gender:"女",age:23})
  注意两点,第一是n,第二是23旁边没有括号了,也就意味着该值不是字符型而是数值型。n实际上是可有可无的,用于捕获create的结果,可以有也可以没有。故而,“n:患者”也可以写成“:患者”,结果是一样的。
 好了,另一个与Create齐名的语法也必须介绍了,这就是:merge,非常非常重要。Merge好似if-else语句,基本逻辑是先检测merge后面的条件,看看有没有匹配的返回值,如果有则执行on merge分支,如果没有则走on create。逻辑很简单,humane:看是否需要merge,找到的话就合并,没找到就新建。
  首先,merge条件部分可以单独执行,不过意义不大:
  还是用例子说明:
  1. merge (x:患者{gender:"男"})
  2. on match set x.name = "小明", x.birthday = 2007/06/02
  3. on create set x.created_time = timestamp()
  结果如图,虽然执行成功:
  但年龄还是有问题:
  到stackOverFlow上找了一下,都说需要手工将时间转成timestamp,因为Neo4j只有一个timestamp()函数而且还没有参数,很多人在抱怨这个问题,估计官方日后一定会增强这方面的功能。
 执行了如下语句后,激活了On create分支,因为数据库中目前并没有 性别是“P”的患者:
  1. merge (x:患者{gender:"P"})
  2. on match set x.name = "小明", x.birthday = "2007/06/02"
  3. on create set x.created_time = timestamp()
  结果如图:


2. Update
  更新的操作实际上是由set命令完成的,首先要定位到待修改的节点或联系,然后进行修改。举个例子:
  1. match (x:患者) where x.gender="男" set x.age=100 return x
  这个例子说明不仅可以使用set更改值,还可以更改值类型,比如从string改为integer。

3 . Retrieve
  实际上,查询或检索这一操作是Cypher实际应用中使用次数最频繁的,类似SQL数据库中的SELECT。在Neo4j中,主要是由Match及其后续限定的Where从句构成。
 比如,通过如下语句新增一个节点,现在数据库中有一男一女两个节点:
  1. create (:患者{gender:"男",age:"23"})
  输入如下语句,返回标签为“患者”的所有节点(当前是两个):
  1. match(x:患者) return x
  输入如下语句,返回标签为“患者”并且性别为“女”的所有节点(当前是一个
  1. match (x:患者) where x.gender="女" return x
  Where从句的语法和SQL非常相似,比如is not null或者=,之间还可以使用and、or等逻辑运算符进行组合。并且,除了Create和Delete语句,其他所有语句都应该以return结尾,否则报错。
 还有一个就是Optional Match,其他都一样,差别在于没找到Match不返回任何结果,而Optional Match返回NULL,如下图的 records”所示:
  在Match查找前,可以进行定位以加快检索速度和效率。一般而言,Cypher语句以Start开始,每一条查询语句可以有多个起始点(starting points),借助start可以制定Legacy index,虽然这个东东现在已经被schema取代了,但为了后向兼容还是保留了基本功能,如下例所示:
  1. start n = node:nodesIndx (Gender = "男") return n
  然而,实际应用中,还有一个重要的检索功能必须掌握,那就是所谓的“Aggregation”。这种聚合实质上是grouping,就是对结果进行统计操作,小到count、max、min,大到stdev、stdevp,更不用说distinct了。比如将之前的例子的返回值加一个count:
  1. match (x:患者) where x.gender="女" return count(x)
  结果是1,如下图所示:
  OK,another trick,使用distinct:
  1. match (x:患者) where x.age="23" return count(distinct x.gender)
  结果如下,返回2,但如果是x.age则只是1啦:
  查询部分先总结到这儿。

4. Delete
  删除任何东西都可以使用Delete,但将上述创建的所有内容一口气删除,不能使用:
  1. match (n)
  2. delete n
  而应该使用:
  1. match (n)
  2. detach delete n
  因为使用第一种方式,会报错:“Cannot delete node, because it still has relationships.”。究其原因,在于高版本的Neo4j加强了数据保护,对于有联系的节点,需要先删除联系再删除节点。然而,使用detach便开启了弱保护机制。
  但是,还有个好用的东东叫remove,专门用来删除属性和标签,比delete安全一些。比如:
  1. match (x:患者{gender:"P"}) remove x.created_time return x
  结果如下图,created_time属性就被删除了:

5. 总结
  之前说Cypher的优化主要是读操作,原因就在于所有操作(Create、Set、Delete或Remove)第一步就是要执行match,而match就是读操作,对特定节点或联系的定位都依赖于读操作。所以,读操作在图数据库中使用的是如此广泛和普遍,以至于成为主要的优化对象一点也不为过。
 已经写成长文了,这篇就先到此为止吧。

五岳之巅
2017年5月21日(孟菲斯时间)
11:57
终稿于UM, FIT



相关文章
|
运维 架构师 测试技术
如何开发一个软件
软件开发
1439 0
|
JavaScript
​​​​Typescript 接口 和继承 数组处理
ts的基础数据类型,可用来处理一般数据,但是碰到后台传入的复杂对象数组的时候,我们可以使用ts中的接口来定义处理
171 0
|
C语言 芯片
【嵌入式系统】存储器映射与寄存器映射原理
【嵌入式系统】存储器映射与寄存器映射原理
611 0
【嵌入式系统】存储器映射与寄存器映射原理
|
数据挖掘 数据处理 C++
Pandas VS Polars:迅如闪电的全新体验
Pandas VS Polars:迅如闪电的全新体验
312 1
|
10月前
|
人工智能 IDE 开发工具
《C++人工智能开发 IDE 全解析:助力智能创新之路》
本文深入探讨了几款适合 C++ 人工智能开发的 IDE,包括 Visual Studio、CLion、Eclipse CDT 和 Qt Creator。每款 IDE 都有其独特的优势,如 Visual Studio 的强大调试工具、CLion 的代码导航和 CMake 支持、Eclipse CDT 的跨平台能力和丰富的插件生态系统,以及 Qt Creator 在界面开发方面的卓越表现。开发者应根据项目需求、团队协作和个人习惯选择最合适的 IDE,以提升开发效率和体验。
231 16
|
9月前
|
存储 运维 负载均衡
Hologres 查询队列全面解析
Hologres V3.0引入查询队列功能,实现请求有序处理、负载均衡和资源管理,特别适用于高并发场景。该功能通过智能分类和调度,确保复杂查询不会垄断资源,保障系统稳定性和响应效率。在电商等实时业务中,查询队列优化了数据写入和查询处理,支持高效批量任务,并具备自动流控、隔离与熔断机制,确保核心业务不受干扰,提升整体性能。
239 11
|
Kubernetes 开发者 Docker
Docker技术概论(8):Docker Desktop原生图形化管理(二)
Docker技术概论(8):Docker Desktop原生图形化管理(二)
269 2
|
机器学习/深度学习 自然语言处理 数据可视化
时序预测的三种方式:统计学模型、机器学习、循环神经网络
时序预测是一类经典的问题,在学术界和工业界都有着广泛的研究和应用。甚至说,世间万物加上时间维度后都可抽象为时间序列问题,例如股票价格、天气变化等等。关于时序预测问题的相关理论也极为广泛,除了经典的各种统计学模型外,当下火热的机器学习以及深度学习中的循环神经网络也都可以用于时序预测问题的建模。今天,本文就来介绍三种方式的简单应用,并在一个真实的时序数据集上加以验证。
729 0
时序预测的三种方式:统计学模型、机器学习、循环神经网络
|
网络协议 Windows
Wireshark的下载安装及简单使用教程
Wireshark的下载安装及简单使用教程
523 0
|
算法 NoSQL 容器
1.贪心理论与常见的证明方法
1.贪心理论与常见的证明方法