Dongxing's Wiki Dongxing's Wiki
首页
  • 剑指 Offer
  • LeetCode
  • 算法与数据结构
  • Python 语言
  • Web 开发
  • Hive
  • Elastic Search
  • 机器学习
  • NLP
  • 检索技术
  • 数据分析
  • 经验笔记
  • Linux 配置
  • 博客进化记
  • 杂谈
GitHub (opens new window)
首页
  • 剑指 Offer
  • LeetCode
  • 算法与数据结构
  • Python 语言
  • Web 开发
  • Hive
  • Elastic Search
  • 机器学习
  • NLP
  • 检索技术
  • 数据分析
  • 经验笔记
  • Linux 配置
  • 博客进化记
  • 杂谈
GitHub (opens new window)
  • 博客进化记

    • hexo博客搭建小记
    • 终于,忍不住自己造轮子做了一个博客系统。
    • Typecho 环境配置和博客搭建
    • VuePress搭建Wiki站
  • 杂谈

    • neo4j的Cypher查询语法笔记
      • 语法
        • 值和类型
        • 命名
        • CASE语句
        • 参数
        • 操作符
        • 注释
        • 模式 Pattern
        • 列表 List
        • 映射 Map
        • 其他
      • 查询语句
        • MATCH
        • OPTIONAL MATCH
        • RETURN
        • WITH
        • UNWIND
        • WHERE
        • ORDER BY
        • SKIP 和 LIMIT
        • CREATE
        • DELETE
        • SET
        • REMOVE
        • FOREACH
        • MERGE
        • UNION
        • 其他
      • 方法(函数)
    • 短域名站点 aka.ci
    • 服务计算课程总结
    • 校招经验笔记
  • HomeLab搭建小记

    • 碎碎念
    • 搞定公网访问
  • 杂谈
  • 杂谈
anthony
2018-10-11
目录

neo4j的Cypher查询语法笔记

官方文档 : https://neo4j.com/docs/developer-manual/current/cypher/

# 语法

# 值和类型

  • 字面量/属性值
  • 节点、关系和路径
  • map和list类型

# 命名

大小写敏感 node的类型名,建议以 PascalCasing relationship的类型名,建议以全大写命名 变量命名多为小写 还有一些保留关键字,如 true, false, null 等

# CASE语句

MATCH (n)
RETURN
CASE
WHEN n.eyes = 'blue'
THEN 1
WHEN n.age < 40
THEN 2
ELSE 3 END AS result
1
2
3
4
5
6
7
8

# 参数

构造查询时可以用 $param 占位填充参数,避免拼接字符串的麻烦。 Parameters.

{
  "name" : "Michael"
}
1
2
3

Query.

MATCH (n:Person)
WHERE n.name STARTS WITH $name
RETURN n.name
1
2
3

# 操作符

# 注释

使用双斜线 //

# 模式 Pattern

使用pattern来描述节点、关系和路径。

//表示节点和关系(支持加入类型和属性信息)
(a {name: 'value'})-[r:REL_TYPE]->(b)

//直接数字指定长度,而无需手写节点
(a)-[*2]->(b) 相当于 (a)-->()-->(b)

//长度可以是范围
(a)-[:KNOWS*3..5]->(b) // 用途:查找3-5度人脉

//不限长度
(a)-[*]->(b)

//定义变量来表示一条路径
p = (a)-[*3..]->(b)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 列表 List

// list 字面量:
//query
RETURN [x IN range(0,10) WHERE x % 2 = 0] AS result
//result
[0,2,4,6,8,10]

//query
RETURN [x IN range(0,10)| x^3] AS result
//result
[0.0,1.0,8.0,27.0,64.0,125.0,216.0,343.0,512.0,729.0,1000.0]

// list应用于查询中:
//query (查询由某人出演的所有电影的年份,返回值封装为列表)
MATCH (a:Person { name: 'Charlie Sheen' })
RETURN [(a)-->(b) WHERE b:Movie | b.year] AS years
//result
[1979,1984,1987]

//使用 collect 可以将数据整理为一个 list 列表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 映射 Map

// map字面量
RETURN { key: 'Value', listKey: [{ inner: 'Map1' }, { inner: 'Map2' }]}

// map应用于查询
//query
MATCH (actor:Person { name: 'Charlie Sheen' })-[:ACTED_IN]->(movie:Movie)
RETURN actor { .name, .realName, movies: collect(movie { .title, .year })}
//result
{movies -> [{year -> 1979, title -> "Apocalypse Now"},{year -> 1984, title -> "Red Dawn"},{year -> 1987, title -> "Wall Street"}], realName -> "Carlos Irwin Estévez", name -> "Charlie Sheen"}

1
2
3
4
5
6
7
8
9
10

# 其他

日期时间、null处理、三维空间距离的处理等部分略过。

# 查询语句

查询语句一览: https://neo4j.com/docs/developer-manual/current/cypher/clauses/

# MATCH

查找节点:

MATCH (:Person { name: 'Oliver Stone' })--(movie:Movie)
RETURN movie.title
1
2

查找关系:

MATCH (wallstreet { title: 'Wall Street' })<-[r:ACTED_IN]-(actor)
RETURN r.role

// 使用 relationships 列出路径中的所有关系
//下面语句查询和charlie共同出演电影的人,假设数据中找到两个人,则返回这两个路径,每个路径是一个list其中包含两条acted_in关系。
MATCH p =(actor { name: 'Charlie Sheen' })-[:ACTED_IN*2]-(co_actor)
RETURN relationships(p)
//result
[:ACTED_IN[0]{role:"Bud Fox"},:ACTED_IN[1]{role:"Carl Fox"}]
[:ACTED_IN[0]{role:"Bud Fox"},:ACTED_IN[2]{role:"Gordon Gekko"}]
1
2
3
4
5
6
7
8
9
10

查找最短路径(shortestPath, allShortestPaths):

//query 查找两人之间的无向最短路径,15步以内。
MATCH (martin:Person { name: 'Martin Sheen' }),(oliver:Person { name: 'Oliver Stone' }), p = shortestPath((martin)-[*..15]-(oliver))
RETURN p
//result
(1)-[ACTED_IN,1]->(5)<-[DIRECTED,3]-(3)

//添加WHERE筛选,要求不把父子关系考虑在内
MATCH (charlie:Person { name: 'Charlie Sheen' }),(martin:Person { name: 'Martin Sheen' }), p = shortestPath((charlie)-[*]-(martin))
WHERE NONE (r IN relationships(p) WHERE type(r)= 'FATHER')
RETURN p

//如有多条最短路径,上面的只会返回一条,可使用all返回全部
MATCH (martin:Person { name: 'Martin Sheen' }),(michael:Person { name: 'Michael Douglas' }), p = allShortestPaths((martin)-[*]-(michael))
RETURN p

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# OPTIONAL MATCH

用法类似于match,但会用null来填充找不到的值。

MATCH (a:Movie { title: 'Wall Street' })
OPTIONAL MATCH (a)-[r:ACTS_IN]->()
RETURN a.title, r
//result
a.title = "Wall Street"
r = <null>
1
2
3
4
5
6

# RETURN

对取出的值进行投影,并返回

// 使用 * 表示返回所有元素
MATCH p =(a { name: 'A' })-[r]->(b)
RETURN *

// 使用 labels 获取节点或关系的标签
MATCH (robert:Critic)
RETURN robert, labels(robert)

// 使用 AS 起别名
MATCH (a { name: 'A' })
RETURN a.age AS SomethingTotallyDifferent

// return 不仅可以返回节点、关系、路径,也可以支持用更多表达式来定义返回值!
MATCH (a { name: 'A' })
RETURN a.age > 30, "I'm a literal",(a)-->()
//result
a.age > 30    =  true
"I'm a literal"    =  "I'm a literal"
a)-->()   =  [(0)-[BLOCKS,1]->(1),(0)-[KNOWS,0]->(1)]

// 使用DISTINCT去重
MATCH (a { name: 'A' })-->(b)
RETURN DISTINCT b

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# WITH

with相当于一个中转,收集处理前一个match的值,并用作后面使用

//  查询和david有关,且至少有一条出边的节点
MATCH (david { name: 'David' })--(otherPerson)-->()
WITH otherPerson, count(*) AS foaf
WHERE foaf > 1
RETURN otherPerson.name

// 查询和Anders有关的节点,按姓名进行排序且只取top1,然后对这一个节点查找其关联节点并返回
// 这样相当于先取出并筛选了精确需要的数据,再以这一部分数据去提取相关信息,避免第一次时查出大量无用信息
MATCH (n { name: 'Anders' })--(m)
WITH m
ORDER BY m.name DESC LIMIT 1
MATCH (m)--(o)
RETURN o.name
1
2
3
4
5
6
7
8
9
10
11
12
13

# UNWIND

将list展开成一系列行的形式。

//query 先将列表展开,进行了去重,然后又collect成列表
WITH [1, 1, 2, 2] AS coll
UNWIND coll AS x
WITH DISTINCT x
RETURN collect(x) AS setOfVals
//result
[1,2]
1
2
3
4
5
6
7

# WHERE

WHERE可设置筛选条件,且WHERE是和MATCH同时进行筛选,而不是先MATCH出来再WHERE筛选。

基本用法:

MATCH (n)-[k:KNOWS]->(f)
WHERE k.since < 2000
RETURN f.name, f.age, f.email

MATCH (n)
WHERE n:Swedish
RETURN n.name, n.age

// exists 可判断是否存在
MATCH (n)
WHERE exists(n.belt)
RETURN n.name, n.belt

1
2
3
4
5
6
7
8
9
10
11
12
13

字符串和正则:

// 字符串支持 STARTS WITH、ENDS WITH、CONTAINS、NOT
MATCH (n)
WHERE n.name STARTS WITH 'Pet'
RETURN n.name, n.age

// 支持正则表达式 
MATCH (n)
WHERE n.name =~ 'Tim.*'
RETURN n.name, n.age

// 要使用两个反斜杠来escape?

// 整个式子前缀 (?) 来表示整个式子大小写不敏感
MATCH (n)
WHERE n.name =~ '(?i)AND.*'
RETURN n.name, n.age

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

筛选pattern:

MATCH (n)
WHERE (n)-[:KNOWS]-({ name: 'Timothy' })
RETURN n.name, n.age
1
2
3

IN :

MATCH (a)
WHERE a.name IN ['Peter', 'Timothy']
RETURN a.name, a.age
1
2
3

# ORDER BY

order by默认升序,加入desc表示降序排列。 null在升序时排在最后,在降序时排在最前。

MATCH (n)
RETURN n.name, n.age
ORDER BY n.name DESC
1
2
3

# SKIP 和 LIMIT

skip表示跳过几行,limit表示返回几行。

// 返回第2,3行
MATCH (n)
RETURN n.name
ORDER BY n.name
SKIP 1
LIMIT 2
1
2
3
4
5
6

# CREATE

创建节点:

// 创建节点。一次可创建多个,可加多个标签,可加属性,可在创建后返回此节点
CREATE (a:Person:Swedish { name: 'Andy' }) ,(m)
RETURN a.name
1
2
3

创建关系:

// 可以指定关系的标签(类型)和属性。
MATCH (a:Person),(b:Person)
WHERE a.name = 'A' AND b.name = 'B'
CREATE (a)-[r:RELTYPE { name: a.name + '<->' + b.name }]->(b)
RETURN type(r), r.name
1
2
3
4
5

创建整条路径:

// 创建3个节点和2条关系
CREATE p =(andy { name:'Andy' })-[:WORKS_AT]->(neo)<-[:WORKS_AT]-(michael { name: 'Michael' })
RETURN p
1
2
3

创建时可采用传参数占位的方式:

//参数
{
  "props" : [ {
    "name" : "Andy",
    "position" : "Developer"
  }, {
    "name" : "Michael",
    "position" : "Developer"
  } ]
}

//语句
// UNWIND可以把列表展开,而SET则是用列表中的每个属性,覆盖n原来的属性。
UNWIND $props AS map
CREATE (n)
SET n = map

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# DELETE

用于删除节点、关系和路径 删除时如果节点有关系,必须显式删除关系,但如果用 DETACH DELETE则会自动删除相关关系。

MATCH (n { name: 'Andy' })
DETACH DELETE n
1
2

只删除关系,而不删除节点:

MATCH (n { name: 'Andy' })-[r:KNOWS]->()
DELETE r
1
2

# SET

set用于更新节点或关系上的属性和标签。

// 新增或更新属性
MATCH (n { name: 'Andy' })
SET n.surname = 'Taylor'
RETURN n.name, n.surname

// 也可以将一个map或另一节点的属性赋予当前节点。注意:当前节点的原有属性都将被清除。
MATCH (at { name: 'Andy' }),(pn { name: 'Peter' })
SET at = pn
RETURN at.name, at.age, at.hungry, pn.name, pn.age

// 某个属性set为null,或者整个节点set为{},可以实现删除属性的效果

// 使用 += 而不是 = ,可以实现属性的增补,即,原来没有的属性会新增,原来有的属性且有新值的属性会更新,原来有但新值没有指定的属性会保持原样
MATCH (p { name: 'Peter' })
SET p += { age: 38, hungry: TRUE , position: 'Entrepreneur' }
RETURN p.name, p.age, p.hungry, p.position

// set 也可以用来设置标签
MATCH (n { name: 'George' })
SET n:Swedish:Bossman  // 设置了多个标签
RETURN n.name, labels(n) AS labels

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# REMOVE

与SET相对应,REMOVE可以移除标签和属性。

// 移除属性
MATCH (a { name: 'Andy' })
REMOVE a.age
RETURN a.name, a.age
// 移除标签
MATCH (n { name: 'Peter' })
REMOVE n:German
RETURN n.name, labels(n)

1
2
3
4
5
6
7
8
9

# FOREACH

// 使用nodes()提取路径中的节点,foreach为每个节点赋值
MATCH p =(begin)-[*]->(END )
WHERE begin.name = 'A' AND END .name = 'D'
FOREACH (n IN nodes(p)| SET n.marked = TRUE )
1
2
3
4

# MERGE

当节点存在时merge可以查找它,当节点不存在时merge可以创建并返回它,相当于create和match的结合。

// 先查找一个节点所在城市,如果城市存在则查找返回,如果城市不存在则创建返回
MATCH (person:Person)
MERGE (city:City { name: person.bornIn })
RETURN person.name, person.bornIn, city

1
2
3
4
5

可以分别指定创建还是查找节点时所进行的操作:

MERGE (keanu:Person { name: 'Keanu Reeves' })
ON CREATE SET keanu.created = timestamp()
ON MATCH SET keanu.lastSeen = timestamp()
RETURN keanu.name, keanu.created, keanu.lastSeen
1
2
3
4

merge也可以应用于对关系的操作。

// 首先要保证要match的person节点存在,然后merge查找或创建city节点,然后merge查找或创建borin关系
MATCH (person:Person)
MERGE (city:City { name: person.bornIn })
MERGE (person)-[r:BORN_IN]->(city)
RETURN person.name, person.bornIn, city
1
2
3
4
5

# UNION

可以将两个查询的结果合并起来

// 不加 ALL,可以去重
MATCH (n:Actor)
RETURN n.name AS name
UNION
MATCH (n:Movie)
RETURN n.title AS name

// 加 ALL, 如果有重复,包含重复
MATCH (n:Actor)
RETURN n.name AS name
UNION ALL 
MATCH (n:Movie)
RETURN n.title AS name
1
2
3
4
5
6
7
8
9
10
11
12
13

# 其他

省略了以下部分的内容,详见文档: LOAD CSV CALL [...YIELD]

# 方法(函数)

支持的函数列表:https://neo4j.com/docs/developer-manual/current/cypher/functions/

上次更新: 2022/11/11, 2:11:00
VuePress搭建Wiki站
短域名站点 aka.ci

← VuePress搭建Wiki站 短域名站点 aka.ci→

Theme by Vdoing | Copyright © 2017-2023 anthony 京ICP备17072417-3
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式