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



相关文章
|
缓存 NoSQL 数据库
探秘Redis读写策略:CacheAside、读写穿透、异步写入
本文介绍了 Redis 的三种高可用性读写模式:CacheAside、Read/Write Through 和 Write Behind Caching。CacheAside 简单易用,但可能引发数据不一致;Read/Write Through 保证数据一致性,但性能可能受限于数据库;Write Behind Caching 提高写入性能,但有数据丢失风险。开发者应根据业务需求选择合适模式。
2809 2
探秘Redis读写策略:CacheAside、读写穿透、异步写入
|
存储 安全 物联网
操作系统的心脏:深入理解现代操作系统架构与核心技术
本文旨在为读者提供一个关于现代操作系统(OS)架构和核心技术的全面概述。通过分析OS的主要组件、功能以及它们如何协同工作,本文揭示了操作系统在计算机系统中的核心地位及其复杂性。我们将探讨进程管理、内存管理、文件系统和输入/输出(I/O)等关键技术,并讨论它们对系统性能的影响。此外,本文还将涵盖一些最新的操作系统趋势和技术,如云计算、虚拟化和物联网(IoT)。通过阅读本文,读者将获得对操作系统内部运作方式的深刻理解,这对于软件开发人员、IT专业人士以及对计算机科学感兴趣的任何人来说都是宝贵的知识。
|
人工智能 JSON 数据可视化
别再盲目训练了!选对这5个框架,让你的模型效率提升80%
AI技术博主详解2026大模型落地实战:厘清LoRA、QLoRA、SFT/DPO等核心概念,对比LLaMA-Factory(可视化首选)、PEFT(灵活开发)、FastChat(开箱即用)等5大主流框架,手把手带新手用LLaMA-Factory完成数据准备、微调与效果评估,零代码快速打造专属模型。(239字)
389 0
|
12月前
|
存储 机器学习/深度学习 人工智能
RAG系统嵌入模型怎么选?选型策略和踩坑指南
嵌入是RAG系统的核心,直接影响检索质量。本文详解嵌入原理,解析稠密/稀疏、长上下文、多向量等类型,梳理选型关键:领域匹配、上下文长度、维度与成本,并结合MTEB基准给出实用建议,助你为业务挑选高效稳健的嵌入方案。
1317 3
RAG系统嵌入模型怎么选?选型策略和踩坑指南
|
安全 物联网 Unix
什么是安全操作系统?
什么是安全操作系统?
894 2
|
存储
数据结构:图文详解单链表的各种操作(头插法,尾插法,任意位置插入,删除节点,查询节点,求链表的长度,清空链表)
数据结构:图文详解单链表的各种操作(头插法,尾插法,任意位置插入,删除节点,查询节点,求链表的长度,清空链表)
3352 0
Java 线程同步的四种方式,最全详解,建议收藏!
本文详细解析了Java线程同步的四种方式:synchronized关键字、ReentrantLock、原子变量和ThreadLocal,通过实例代码和对比分析,帮助你深入理解线程同步机制。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
Java 线程同步的四种方式,最全详解,建议收藏!
|
机器学习/深度学习 Python
扩散模型的基本原理
扩散模型的基本原理
927 2
|
Java 开发者 Spring
深入理解Spring Boot中的自动配置原理
深入理解Spring Boot中的自动配置原理
3026 1
|
机器学习/深度学习 存储 自然语言处理
Jieba分词模式详解、词库的添加与删除、自定义词库失败的处理
Jieba(结巴)是一个中文分词第三方库,它可以帮助我们将一段中文文本分成一个个独立的词语。Jieba具有以下特点: 简单易用:Jieba提供了简洁的API接口,易于使用和扩展。可以快速地实现中文分词功能。 高效准确:Jieba采用了基于前缀词典和动态规划算法的分词方法,能够高效准确地处理各种中文文本。 支持多种分词模式:Jieba提供了三种分词模式:精确模式、全模式和搜索引擎模式,可以根据不同的应用场景选择合适的模式。
Jieba分词模式详解、词库的添加与删除、自定义词库失败的处理