Neo4j Cypher语法(一)
目录
Cypher手册详解
最近在研究知识图谱,避免不了的涉及到了图数据库和图算法,我们用的图数据库是neo4j,对其CQL语法做一个记录。整篇文章是对官网Cypher手册的翻译(正常访问超级慢,也许要翻墙),同时做了一些删减,例如地理函数和时间函数,和我的项目关系不大,就没有学习,对于官网的一些示例加上了结果的截图和自己的理解,本博文基于Neo4j3.5.3,其余版本可能会报错。如有错误,还麻烦各位大佬指正,非常感谢。
1 背景
什么是neo4j?
Neo4j是一个高性能的,NOSQL图形数据库,它将结构化数据存储在网络上而不是表中。它是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java持久化引擎,但是它将结构化数据存储在网络(从数学角度叫做图)上而不是表中。Neo4j也可以被看作是一个高性能的图引擎,该引擎具有成熟数据库的所有特性。程序员工作在一个面向对象的、灵活的网络结构下而不是严格、静态的表中--但是他们可以享受到具备完全的事务特性、企业级的数据库的所有好处。
neo4j的呈现形式:Neo4j中不存在表的概念,只有两类:节点(Node)和关系(Relation),可以简单理解为图里面的点和边。
在数据查询中,节点一般用小括号(),关系用中括号[]。
当然也隐含路径的概念,是用节点和关联表示的,如:(a)-[r]->(b),表示一条从节点a经关联r到节点b的路径。
关系:neo4j中是单向关系,严格的来说不具备双向或者无向的关系。但是merge (a)-[r]-(b)这样的语句创建的关系可以理解为是双向的,但是neo4j中比较尴尬的一点是这样可以理解为无向关系的关系,在web呈现时是带着单向箭头的。
属性:节点和关系都可以具备属性。
标签:代表节点的类型,一个节点可以有0个、1个或者多个标签。
类型:代表关系的类型,一条关系可以有0个或者1个,一条边不能具有多个type。
2 唯一性
在模式匹配时,neo4j确保不会在单个模式中多次找到相同图形关系的匹配。举例,在寻找朋友的朋友时,不会返回所述用户自身。
CREATE (adam:User { name: 'Adam' }),(pernilla:User { name: 'Pernilla' }),(david:User { name: 'David'}),(adam)-[:FRIEND]->(pernilla),(pernilla)-[:FRIEND]->(david)
寻找Adam朋友的朋友
MATCH (user:User { name: 'Adam' })-[r1:FRIEND]-()-[r2:FRIEND]-(friend_of_a_friend)
RETURN friend_of_a_friend.name AS fofName
返回David
因为r1和r2在同一个模式中,又是不同的变量名,所以不会返回同一条关系,即图形中的有向边。检验:在两个子句中用不同的变量名就不管用
MATCH (user:User { name: 'Adam' })-[r1:FRIEND]-(friend)
MATCH (friend)-[r2:FRIEND]-(friend_of_a_friend)
RETURN friend_of_a_friend.name AS fofName
但是只要在一个模式中,即使拆分了多个子模式也不会匹配到同一关系,如下所示。
MATCH (user:User { name: 'Adam' })-[r1:FRIEND]-(friend),(friend)-[r2:FRIEND]-(friend_of_a_friend)
RETURN friend_of_a_friend.name AS fofName
3 语法
3.1 命名规则
必须以字母开头,不能以数字开头。
节点标签:驼峰式命名,关系类型:全大写命名。
3.2 表达式
十进制、十六进制:0x13ff,0xFCA39
八进制整数文字:01372、02127
字符串、bool类型
属性:n.prop、x.prop、rel.thisProperty
动态属性:n["prop"], rel[n.city + n.zip], map[coll[0]]
参数:$param, $0
表达式列表:['a', 'b'], [1, 2, 3], ['a', 2, n.property, $param], [ ].
函数调用:length(p) nodes(p)
聚合函数,路径模式
正则表达式:a.name =~ 'Tim.*'
字符串匹配:
surname STARTS WITH 'Sven',
surname ENDS WITH 'son' or a.surname CONTAINS 'son'
CASE表达式
3.2.1 字符串常用的转义序列
\t Tab键 \b 后退键 \n 新起一行 \r 回车符 \f 制表符 \’ 单引号 \’’双引号
\\ 反斜杠的转义
3.2.2 CASE表达式
计算表达式,并按顺序与WHEN子句进行比较,直到找到匹配项。 如果未找到匹配项,则返回ELSE子句中的表达式。 但是,如果没有ELSE情况且未找到匹配项,则返回null。
CASE test
WHEN value THEN result
[WHEN ...]
[ELSE default]
END
建表语句:
create (A:Person {name:'Alice', eyes:"brown",age:38}),
(B:Person {name:"Bob", eyes:"blue", age:25}),
(C:Person {name:"Charlie", eyes:'green',age:53}),
(D:Person {name:"Daniel", eyes:'brown'}),
(E:Person {name:'Eskil',eyes:"blue",age:41,array:['one','two','three']}),
(A)-[:KNOWS]->(B),
(A)-[:KNOWS]->(C),
(B)-[:KNOWS]->(D),
(C)-[:KNOWS]->(D),
(B)-[:MARRIED]->(E)
测试语句1:
MATCH (n:Person)
RETURN n.name,
CASE n.eyes
WHEN 'blue'
THEN 1
WHEN 'brown'
THEN 2
ELSE 3 END AS result
测试语句2:
MATCH (n:Person)
RETURN n.name,
CASE
WHEN n.eyes = 'blue'
THEN 1
WHEN n.age < 40
THEN 2
ELSE 3 END AS result
测试语句3:
我们看到建表语句中,存在一些节点时没有age属性的,我们希望返回一个age_10_years_ago的值,假设不存在age属性,将该值返回-1。我们按照如下的方式来试写查询语句,期望对于Daniel返回-1,因为他不具备age属性。但是并不如意:
MATCH (n:Person)
RETURN n.name,
CASE n.age
WHEN n.age IS NULL THEN -1
ELSE n.age - 10 END AS age_10_years_ago
原因:n.age是一个整型,而n.age IS NULL是一个bool值,所以不会走到WHEN n.age IS NULL THEN -1这个对应的分支,需要换成如下的写法:
MATCH (n:Person)
RETURN n.name,
CASE
WHEN n.age IS NULL THEN -1
ELSE n.age - 10 END AS age_10_years_ago
换一种方式理解,就是常用的switch(n.age), 不会等于 n.age is null这个case ,想要返回-1直接写成如下方式即可。
MATCH (n:Person)
RETURN n.name,
CASE n.age
WHEN NULL THEN -1
ELSE n.age - 10 END AS age_10_years_ago
3.3 变量与保留关键字
变量仅在同一查询部分中可见
变量不会转移到后续查询中。 如果使用WITH将多个查询部分链接在一起,则必须在WITH子句中列出变量以将其转移到下一部分。
保留关键字不能用于变量名、函数名、参数。
3.4 参数
Cypher支持使用参数查询。这意味着开发人员不必使用字符串构建来创建查询。此外,参数使得Cypher的执行计划缓存更加容易,从而缩短了查询执行时间。
参数可用于:文字和表达式
节点和关系id
仅用于显式索引:索引值和查询
参数不能用于以下构造,因为它们构成了编译到查询计划中的查询结构的一部分:
属性键;所以,MATCH(n)WHERE n.$ param ='something'无效
关系类型
标签
参数可以包含字母和数字,以及这些参数的任意组合,但不能以数字或货币符号开头。
3.4.1 参数定义
参数仅仅对当前会话有效,网页刷新变量消失。变量为一个kv的键值对。
:param a:1, b:2或者:param {a: 1, b: 2}以这样的形式来定义参数,注意前面是有冒号的。
MATCH (n:Person)
WHERE n.name = $name
RETURN n
MATCH (n:Person { name: $name })
RETURN n
查看当前的所有参数:
:params
3.4.2 可以使用参数的各种场景
正则表达式:
:param {"regex":".*VM.*"}
match (n:VM) where n.name=~ $regex return n.name
大小写敏感的字符串匹配
:params { "name" : "Michael"}
MATCH (n:Person)
WHERE n.name STARTS WITH $name
RETURN n.name
创建多个带属性带标签的节点
:param {"props" : [ {
"awesome" : true,
"name" : "Andy",
"position" : "Developer"
}, {
"children" : 3,
"name" : "Michael",
"position" : "Developer"
} ]}
UNWIND $props AS properties
CREATE (n:Person)
SET n = properties
RETURN n
判断某个变量在或者不在变量列表中
:param "ids" : [ 0, 1, 2 ]
//判断变量在列表中,如何判断变量不在对应的列表中?not in会报错,<>达不到想要的结果
MATCH (n)
WHERE id(n) IN $ids
RETURN n.name
//判断变量不存在于列表中
match(n:VM) where size([l in [id(n)] where l in $ids ])=0 return n
调用函数
:param "value" : "Michaela"
START n=node:people(name = $value)
RETURN n
3.5 操作符
3.5.1 使用[]
来访问动态计算的属性键 对多个属性键来进行共同筛选
CREATE (a:Restaurant { name: 'Hungry Jo', rating_hygiene: 10, rating_food: 7 }),(b:Restaurant { name: 'Buttercup Tea Rooms', rating_hygiene: 5, rating_food: 6 }),(c1:Category { name: 'hygiene' }),(c2:Category { name: 'food' })
WITH a, b, c1, c2
MATCH (restaurant:Restaurant),(category:Category)
WHERE restaurant["rating_" + category.name]> 6
RETURN DISTINCT restaurant.name
3.5.2 ^完成指数运算
3.5.3字符串判断
STARTS WITH ENDS WITH CONTAINS
3.5.4 使用in进行更加复杂的列表成员操作
RETURN [2, 1] IN [1,[2, 1], 3] AS inList 会return true。
RETURN [1, 2] IN [1, 2] AS inList 会return false 这里的in不是判断认为两个是整体,而是将左边作为一个整体元素,判断左边是否为右边的子元素
如下查询可以用于判断llhs是否至少包含一个也存在于lrhs中的元素
MATCH (n)//判断当前库中的所有节点,有哪些的标签是Person或者Employee
WHERE size([l IN labels(n) WHERE l IN ['Person', 'Employee'] | 1]) > 0
RETURN count(n)
3.5.5 用[]获取列表元素
WITH ['Anne', 'John', 'Bill', 'Diane', 'Eve'] AS names
RETURN names[1..3] AS result
这里的方括号是左闭右开的,
所以会返回[‘John’,‘Bill’]
和C语言一样//表示对应的注释
3.6 模式
模式和模式匹配时Cypher的核心,有效使用Cypher需要对模式有一个正确的理解。
最为简单的模式就是一个双括号括上一个变量名,例如(a) a就是一个变量名
(a)-->(b)
(a)-->(b)<--(c)这样的一系列的节点和关系称之为路径
可以在模式中描述的最简单的属性称之为标签(a:User)-->(b) 同时可以描述具备多个标签的节点(a:User:Admin)-->(b)
3.6.1 指定属性
对于MERGE子句,属性将用作任何现有数据必须具有的形状的附加约束(指定的属性必须与图中的任何现有数据完全匹配)。 如果未找到匹配的数据,则MERGE的行为类似于CREATE,并且将在新创建的节点和关系中设置属性。
3.6.2 关系的模式
类似于节点的标签,对于关系来说叫做类型,但是和节点标签不同的是,关系的类型仅仅只有一种。如果我们想要描述一些数据,使得这种关系可以有一组类型中的任何一种,那么它们都可以在模式中列出,用管道符号将它们分开。像这样(但是仅仅适用于match,不适用于Create和merge):
(a)-[r:TYPE1|TYPE2]->(b)
关系名称通常也可以省略
3.6.3 变量长度的模式匹配
在模式的关系描述中指定长度来进行对应的描述
(a)-[*2]->(b) 等价于 (a)-->()-->(b)
(a)-[*3..5]->(b)这一关系是左闭右闭,即包含3个关系、4个关系、5个关系
(a)-[*3..]->(b) (a)-[*..5]->(b)
需要特别注意的一点是,即使关系是单向的,在如下的语句中,--表示不考虑关系的方向,仍然会反向查找找出走一个关系或者两个关系的节点。
MATCH (me)-[:KNOWS*1..2]-(remote_friend)
WHERE me.name = 'Filipa'
RETURN remote_friend.name
3.7 列表
RETURN range(0, 10) as list ,range(0, 10)[3] as result//将列表中下标索引为3的元素也就是第4个元素返回
与Python不同的是 这里的range是左闭右闭的,即一个列表中有11个元素
range(0, 10)[-3]//倒数第三个元素
RETURN range(0, 10)[0..3]//左闭右开
RETURN range(0, 10)[-5..]或者[..4]//只有在list中的a..b是左闭右开的,路径长度的匹配与range范围中的a..b都左闭右闭的。
//也可以理解为返回倒数5个元素的列表和正数4个元素的列表
RETURN size(range(0, 10)[0..3])//size函数的返回结果是3
3.7.1 列表推导
RETURN [x IN range(0,10) WHERE x % 2 = 0 | x^3] AS result//这里的竖线不是或,而是管道
MATCH (a:Person { name: 'Charlie Sheen' })
RETURN [(a)-->(b) WHERE b:Movie | b.year] AS years
3.8 映射
Cypher坚定地支持映射,对map的处理不太理解。
3.9 使用null
Cypher中的null表示缺失或未定义的值,null并不等于null,不知道的两个值并不意味着它们相等 ,所以null=null会抛出null而不是true。
null IN [1, 2, 3]
null IN [1, null, 3]
null in []
如果使用null来做列表切片的首尾索引值,那么返回值也是null。
原文地址:https://blog.csdn.net/weixin_42348333/article/details/89758617
Neo4j Cypher语法(一)的更多相关文章
- Neo4j Cypher语法(三)
目录 5 函数 5.1 谓词函数 5.2 标量函数 5.3 聚合函数 5.4 列表函数 5.5 数学函数 5.6 字符串函数 5.7 Udf与用户自定义函数 6 模式 6.1 索引 6.2 限制 7 ...
- Neo4j Cypher语法(二)
目录 4 子句 4.1 CREATE 4.2 MATCH 4.3 Match 4.4 Create match return连用来返回一个关系基础 4.5 Optional_match 4.6 Wit ...
- Neo4j 第六篇:Cypher语法
Cypher是图形数据库查询语言事实上的标准. 一,Cypher类型系统 Cypher支持的类型系统分为三类:属性类型,复合类型和结构类型. 1,属性类型 属性类型:Integer.Float.Str ...
- 记录Neo4j上写的简单cypher语法
neo4j是一个高性能的图形数据库,既然是数据库,那么主要操作就是增.删.改.查.所以进入正题: 一.CREATE:创建 语法如下: 1.create(变量名:标签名) :建立一个标签为Animal的 ...
- Cypher语法
cypher是neo4j官网提供的声明式查询语言,非常强大,用它可以完成任意的图谱里面的查询过滤,我们知识图谱的一期项目 基本开发完毕,后面会陆续总结学习一下neo4j相关的知识.今天接着上篇文章来看 ...
- Neo4j Cypher查询语言详解
Cypher介绍 "Cypher"是一个描述性的图形查询语言,允许不必编写图形结构的遍历代码对图形存储有表现力和效率的查询.Cypher还在继续发展和成熟,这也就意味着有可能会出现 ...
- Neo4j Cypher运行示例
示例来源: Neo4j in Action. 0 准备数据 0.1 node (user1 { name: 'John Johnson', type: 'User', email: 'jsmith@e ...
- neo4j 基本语法笔记(全)
按照总监要求看了两天的neo4j 数据库的使用.在网上找了一个基础教程类似于w3c.school的网站(英文 ,中文,中文的翻译的不是很好,如果英文不好可以辅助理解),这个教程基础知识很全全面,从数据 ...
- Neo4j/cypher学习笔记与学习建议
简介 本笔记的主要内容是 cypher 查询语言的编写与使用. 笔记主要整理自w3cschool上的neo4j教程以及Neo4j中文网所提供的cypher中文文档,此外还包括少量从其他个人博客与官方手 ...
随机推荐
- redis慢查询笔记
慢查询 生命周期 两个配置 三个命令 运维经验 生命周期 1.发送命令 2,排队执行命令因为单线程 3.执行命令 4.返回结果 慢查询发生在第三阶段 客户端超时并不一定有慢查询,但慢查询是客户端超时的 ...
- Java-AQS源码详解(细节很多!)
ReentrantLock调用lock()时时序图: addWaiter方法: enq方法:自旋 它维护了一个volatile int state(代表共享资源)和一个FIFO线程等待队列(多线程争用 ...
- Linux .bashrc
Set environmental variable // 用:隔开 export PATH=$PATH:<PATH >:<PATH >:<PATH >:----- ...
- nginx详解(代理服务器的解释+nginx 在linux 下的安装+nginx.conf 中的配置解释)
一.概论 1.什么是代理服务器 代理服务器,客户机在发送请求时,不会直接发送给目的主机,而是先发送给代理服务器,代理服务接受客户机请求之后,再向主机发出,并接收目的主机返回的数据,存放在代理服务器的硬 ...
- MySql锁和事务隔离级别
在讲mysql事物隔离级别之前,我们先简单说说mysql的锁和事务. 一:数据库锁 因为数据库要解决并发控制问题.在同一时刻,可能会有多个客户端对同一张表进行操作,比如有的在读取该行数据,其他的尝试去 ...
- JVM学习笔记之JDK、JRE、JVM的关系(二)
JDK(Java Development Kit)是针对Java开发员的产品,是整个Java的核心,包括了Java运行环境JRE.Java工具和Java基础类库.Java Runtime Enviro ...
- Android云端APP
使用HbuilderX打包APP 首先创建一个 5+APP+使用MUI项目 <!DOCTYPE html> <html> <head> <meta chars ...
- grep 正则表达式用引号括起来和元字符加反斜杠转义的测试
grep 正则表达式用引号括起来和元字符加反斜杠转义的测试 实验在 grep 命令中的表达式:不加引号,加单引号,加双引号的区别,以及部分元字符前加与不加 `\’ 进行转义的区别.实验环境为“实验楼( ...
- vim在文件末尾增加内容
1.跳到文本的最后一行:按“G”,即“shift+g” 2.跳到最后一行的最后一个字符 : 先重复1的操作即按“G”,之后按“$”键,即“shift+4”.3 o:在当前行下面插入一个新行O:在当前 ...
- docker下载镜像
注意:必须先搜索镜像,否则有时候无法下载 Docker下载Redis镜像并运行容器 .搜索查找镜像 docker search redis .下载镜像 docker pull redis:latest ...