本文以 Neo4j 官网上的 Neo4j Cypher Refcard 3.4为基准,通篇翻译以作学习。即便版本发生改变 ,但其语法以及其作用不会发生太大的变化,放心食用,个人建议原文口味更佳。

Read Query Structure

Read Query Structure
[MATCH WHERE]
[OPTIONAL MATCH WHERE]
[WITH [ORDER BY] [SKIP] [LIMIT]]
RETURN [ORDER BY] [SKIP] [LIMIT]

MATCH

MATCH
MATCH (n:Person)-[:KNOWS]->(m:Person) WHERE n.name = ‘Alice’ [^1]
MATCH (n)–>(m) [^2]
MATCH (n {name:‘Alice’})–>(m) [^3]
MATCH p = (n)–>(m) [^4]
OPTIONAL MATCH (n)-[r]->(m) [^5]

[^1]: 节点模式(Node patterns)可包含标签以及属性
[^2]: MATCH中可以使用所有的模式
[^3]: 具有节点属性的模式
[^4]: 将路径赋值与p
[^5]: 可选模式:空值将用于丢失的部分

WHERE

WHERE
WHERE n.property <> $value [^6]

[^ 6]: WHERE始终是MATCH,OPTIONAL MATCH,WITH或START子句的一部分。 将它放在查询中的不同子句之后将改变它的作用

RETURN

RETURN
RETURN * ^7
RETURN n AS columnName ^8
RETURN DISTINCT n ^9
ORDER BY n.property ^10
ORDER BY n.property DESC ^11
SKIP $skipNumber ^12
LIMIT $limitNumber ^13
SKIP $skipNumber LIMIT $limitNumber ^14
RETURN count(*) [^15]

[^15]: 返回的总数(count - 聚合函数)

WITH

WITH
MATCH (user)-[:FRIEND]-(friend)
WHERE user.name = $name
WITH user, count(friend) AS friends
WHERE friends > 10
RETURN user [^16]

[^16]: WITH语法类似于RETURN。 它明确地分隔查询部分,允许声明要将哪些变量转移到下一个部分。

UNION

UNION
MATCH (a)-[:KNOWS]->(b)
RETURN b.name
UNION
MATCH (a)-[:LOVES]->(b)
RETURN b.name ^17

Write-Only Query Structure

Write-Only Query Structure
(CREATE [UNIQUE] | MERGE) *
[SET | DELETE | REMOVE | FOREACH] *
[RETURN [ORDER BY] [SKIP] [LIMIT]]

Read-Write Query Structure

Read-Write Query Structure
[MATCH WHERE]
[OPTIONAL MATCH WHERE]
[WITH [ORDER BY] [SKIP] [LIMIT]]
(CREATE [UNIQUE] | MERGE) *
[SET | DELETE | REMOVE | FOREACH] *
[RETURN [ORDER BY] [SKIP] [LIMIT]]

CREATE

CREATE
CREATE (n {name: $value}) ^18
CREATE (n $map) ^18
UNWIND $listOfMaps AS properties
CREATE (n) SET n = properties ^18
CREATE (n)-[r:KNOWS]->(m) [^19]
CREATE (n)-[:LOVES {since: $value}]->(m) [^20]

[^19]: 创建具有给定类型和方向的关系; 将变量绑定到它。
[^20]: 使用给定的类型,方向和属性创建关系。

SET

CREATE
SET n.property1 = $value1,
n.property2 = $value2 ^21
SET n = $map [^22]
SET n += $map [^23]
SET n:Person [^24]

[^22]: 设置所有属性。 这将删除任何现有属性
[^23]: 添加和更新属性,同时保留现有属性
[^24]: 向节点添加标签Person

MERGE

MERGE
MERGE (n:Person {name: $value})
ON CREATE SET n.created = timestamp()
ON MATCH SET
n.counter = coalesce(n.counter, 0) + 1,
n.accessTime = timestamp() [^25]
MATCH (a:Person {name: $value1})
MERGE
(a)-[r:KNOWS]->(b:Person {name: $value3}) [^26]

[^25]: 匹配模式或创建模式(如果不存在)。 使用ON CREATE和ON MATCH进行条件更新。
[^26]: MERGE查找或创建附加到节点的子图。

DELETE

DELETE
DELETE n, r ^27
DETACH DELETE n ^28
MATCH (n)
DETACH DELETE n ^29

REMOVE

REMOVE
REMOVE n:Person ^30
REMOVE n.property ^31

FOREACH

FOREACH
FOREACH (r IN relationships(path)|
SET r.marked = true) ^32
FOREACH (value IN coll |
CREATE (:Person {name: value})) ^33

CALL

CALL
CALL db.labels() YIELD label [^34]
CALL java.stored.procedureWithArgs [^35]
CALL db.labels() YIELD label
RETURN count(label) AS count [^36]

[^34]: 这显示了对内置过程db.labels的独立调用,以列出数据库中使用的所有标签。 请注意,在过程名称后面的括号中明确给出了必需的过程参数。
[^35]: 独立调用可以省略YIELD并且还通过语句参数隐式地提供参数,例如, 需要一个参数输入的独立调用可以通过传递参数map {input:‘foo’}来运行。
[^36]: 在较大的查询中调用内置过程db.labels来计算数据库中使用的所有标签。 在较大的查询中调用总是需要传递参数并使用YIELD显式命名结果。

Import

LOAD CSV FROM 'https://neo4j.com/docs/cypher-refcard/3.4/csv/artists.csv' AS line CREATE (:Artist {name: line[1], year: toInteger(line[2])}) ^37

LOAD CSV WITH HEADERS FROM 'https://neo4j.com/docs/cypher-refcard/3.4/csv/artists-with-headers.csv' AS line CREATE (:Artist {name: line.Name, year: toInteger(line.Year)}) ^38

USING PERIODIC COMMIT 500 LOAD CSV WITH HEADERS FROM 'https://neo4j.com/docs/cypher-refcard/3.4/csv/artists-with-headers.csv' AS line CREATE (:Artist {name: line.Name, year: toInteger(line.Year)}) ^39

LOAD CSV FROM 'https://neo4j.com/docs/cypher-refcard/3.4/csv/artists-fieldterminator.csv' AS line FIELDTERMINATOR ';' CREATE (:Artist {name: line[1], year: toInteger(line[2])}) ^40

Operators

General DISTINCT, ., []
Mathematical +,-,*,/,%,^
Comparison =, <>, <, >, <=, >=, IS NULL, IS NOT NULL
Boolean AND, OR, XOR, NOT
String +
List +,IN,[x],[x … y]
Regular Expression =~
String matching STARTS WITH, ENDS WITH,CONTAINS

null

  • null用于表示缺失/未定义的值。
  • null不等于null。 不知道两个值并不意味着它们是相同的值。 所以表达式null = null产生null而不是true。 要检查表达式是否为null,请使用IS NULL。
  • 如果任何参数为null,则算术表达式,比较和函数调用(coalesce除外)将返回null。
  • 尝试访问列表中缺少的元素或不存在的属性会产生null。
  • 在OPTIONAL MATCH子句中,空值将用于模式的缺失部分。

Patterns

(n:Person):带有Person标签的节点。

(n:Person:Swedish):具有Person和Swedish标签的节点。

(n:Person {name: $value})具有声明属性的节点。

()-[r {name: $value}]-()匹配与声明的属性的关系。

(n)-->(m)从n到m的关系。

(n)--(m)n和m之间任意方向的关系。

(n:Person)-->(m)节点n标记为与m有关系的Person。

(m)<-[:KNOWS]-(n)从n到m的KNOWS类型的关系。

(n)-[:KNOWS|:LOVES]->(m)类型为KNOWS或类型为LOVES的关系,从n到m。

(n)-[r]->(m)将关系绑定到变量r。

(n)-[*1..5]->(m)从n到m的1到5个关系之间的可变长度路径。

(n)-[*]->(m)从n到m的任意数量关系的可变长度路径。

(n)-[:KNOWS]->(m {property: $value})从节点n到具有声明属性的节点m的KNOWS类型的关系。

shortestPath((n1:Person)-[*..6]-(n2:Person))找到一条最短的路径。

allShortestPaths((n1:Person)-[*..6]->(n2:Person))找到所有最短的路径。

size((n)-->()-->())计算与模式匹配的路径。

Lists

['a', 'b', 'c'] AS list文字列表在方括号中声明。

size($list) AS len, $list[0] AS value列表可以作为参数传递。

range($firstNum, $lastNum, $step) AS listrange()创建一个数字列表(步骤是可选的),返回列表的其他函数是:labels(),nodes(),relationships(),filter(),extract()。

MATCH p = (a)-[:KNOWS*]->() RETURN relationships(p) AS r 可以使用命名路径和relationships()返回包含可变长度路径的关系列表。

RETURN matchedNode.list[0] AS value, size(matchedNode.list) AS len属性可以是字符串,数字或布尔值的列表。

list[$idx] AS value, list[$startIdx..$endIdx] AS slice可以使用方括号中的idx下标访问列表元素。 无效索引返回null。 可以从start_idx到end_idx的间隔检索切片,每个切片可以省略或为负。 超出范围的元素将被忽略。

UNWIND $names AS name MATCH (n {name: name}) RETURN avg(n.age)使用UNWIND,任何列表都可以转换回单个行。 该示例匹配名称列表中的所有名称。

MATCH (a) RETURN [(a)-->(b) WHERE b.name = 'Bob' | b.age]模式推导可用于从匹配中直接进行自定义投影到列表中。

MATCH (person) RETURN person { .name, .age}可以从节点,关系和其他地图值容易地构建地图投影。

Maps

{name: 'Alice', age: 38, address: {city: 'London', residential: true}}maps用花括号声明,就像属性贴图一样。 支持列表。

WITH {person: {name: 'Anne', age: 25}} AS p RETURN p.person.name访问嵌套映射的属性。

MERGE (p:Person {name: $map.name}) ON CREATE SET p = $mapmaps可以作为参数传递,并用作map或访问键。

MATCH (matchedNode:Person) RETURN matchedNode节点和关系将作为其数据的映射返回。

map.name, map.age, map.children[0]可以通过其键访问映射条目。 密钥无效会导致错误

Predicates

n.property <> $value使用比较运算符。

exists(n.property)使用函数。

n.number >= 1 AND n.number <= 10使用布尔运算符组合谓词。

1 <= n.number <= 10使用链式运算符组合谓词。

n:Person检查节点标签。

variable IS NULL检查某些内容是否为空。

NOT exists(n.property) OR n.property = $value属性不存在或谓词为真

n.property = $value不存在的属性返回null,它不等于任何东西。

n["property"] = $value也可以使用动态计算的属性名称访问属性。

n.property STARTS WITH 'Tim' OR n.property ENDS WITH 'n' OR n.property CONTAINS 'goodie'字符串匹配。

n.property =~ 'Tim.*'字符串正则表达式匹配

(n)-[:KNOWS]->(m)确保模式至少有一个匹配。

NOT (n)-[:KNOWS]->(m)从结果中排除与(n) - [:KNOWS] - >(m)的匹配。

n.property IN [$value1, $value2]检查列表中是否存在元素。

List Predicates

all(x IN coll WHERE exists(x.property))如果列表中的所有元素的谓词为true,则返回true。

any(x IN coll WHERE exists(x.property))如果谓词对于列表中的至少一个元素为true,则返回true。

none(x IN coll WHERE exists(x.property))如果列表中的所有元素的谓词为false,则返回true。

single(x IN coll WHERE exists(x.property))如果谓词对于列表中的一个元素为true,则返回true。

CASE

CASE n.eyes WHEN 'blue' THEN 1 WHEN 'brown' THEN 2 ELSE 3 END从匹配的WHEN值返回THEN值。 ELSE值是可选的,如果缺少则替换为null。

CASE WHEN n.eyes = 'blue' THEN 1 WHEN n.age < 40 THEN 2 ELSE 3 END将第一个WHEN谓词评估中的THEN值返回true。 按顺序评估谓词。

List Expressions

size($list)列表中的元素数量。

reverse($list)反转列表中元素的顺序。

head($list), last($list), tail($list)head()返回第一个,last()列表的最后一个元素。 tail()返回除第一个元素之外的所有元素。 对于空列表,所有返回null。

[x IN list WHERE x.prop <> $value | x.prop]过滤器和提取物的组合以简洁的表示法。

extract(x IN list | x.prop)原始列表中每个元素的表达式值列表。

filter(x IN list WHERE x.prop <> $value)谓词为true的元素的筛选列表。

reduce(s = "", x IN list | s + x.prop)评估列表中每个元素的表达式,累积结果。

Functions

coalesce(n.property, $defaultValue)第一个非null表达式。

timestamp()自UTC时间1970年1月1日午夜起的毫秒数。

id(nodeOrRelationship)关系或节点的内部标识。

toInteger($expr)如果可能,将给定输入转换为整数; 否则返回null。

toFloat($expr)如果可能,将给定输入转换为浮点数; 否则返回null。

toBoolean($expr)如果可能,将给定输入转换为布尔值; 否则返回null。

keys($expr)返回节点,关系或映射的属性名称的字符串表示形式的列表。

properties({expr})返回包含节点或关系的所有属性的映射。

Path Functions

length(path)路径中的关系数。

nodes(path)路径中的节点作为列表。

relationships(path)路径中的关系作为列表。

extract(x IN nodes(path) | x.prop)从路径中的节点提取属性。

Spatial Functions

point({x: $x, y: $y})返回2D笛卡尔坐标系中的点。

point({latitude: $y, longitude: $x})返回2D地理坐标系中的点,坐标以十进制度指定。

point({x: $x, y: $y, z: $z})返回3D笛卡尔坐标系中的点。

point({latitude: $y, longitude: $x, height: $z})返回3D地理坐标系中的点,纬度和经度以十进制度表示,高度以米为单位。

distance(point({x: $x1, y: $y1}), point({x: $x2, y: $y2}))返回表示两点之间的线性距离的浮点数。 返回的单位将与点坐标的单位相同,并且它将适用于2D和3D笛卡尔点。

distance(point({latitude: $y1, longitude: $x1}), point({latitude: $y2, longitude: $x2}))返回两点之间的测地距离(以米为单位)。 它也可以用于3D地理点。

Temporal Functions

date("2018-04-05")返回从字符串解析的日期。

localtime("12:45:30.25")返回没有时区的时间。

time("12:45:30.25+01:00")返回指定时区的时间。

localdatetime("2018-04-05T12:34:00")返回没有时区的日期时间。

datetime("2018-04-05T12:34:00[Europe/Berlin]")返回指定时区的日期时间。

datetime({epochMillis: 3360000})将3360000作为UNIX纪元时间转换为正常的日期时间。

date({year: {year}, month: {month}, day: {day}})还可以使用命名组件的映射来调用所有时间函数。 此示例返回年,月和日组件的日期。 每个函数都支持一组不同的可能组件。

datetime({date: {date}, time: {time}})可以通过组合其他类型来创建时间类型。 此示例从日期和时间创建日期时间。

date({date: {datetime}, day: 5})可以通过从更复杂的类型中进行选择以及覆盖单个组件来创建时间类型。 此示例通过从日期时间中进行选择以及覆盖日期组件来创建日期。

WITH date("2018-04-05") AS d返回d.year,d.month,d.day,d.week,d.dayOfWeek
访问器允许提取时间类型的组件。

Duration Functions

duration("P1Y2M10DT12H45M30.25S")返回1年,2个月,10天,12小时,45分钟和30.25秒的持续时间。

duration.between($date1,$date2)返回两个临时实例之间的持续时间。

WITH duration("P1Y2M10DT12H45M") AS d RETURN d.years, d.months, d.days, d.hours, d.minutes返回1年,14个月,10天,12小时和765分钟。

WITH duration("P1Y2M10DT12H45M") AS d RETURN d.years, d.monthsOfYear, d.days, d.hours, d.minutesOfHour返回1年,2个月,10天,12小时45分钟。

date("2015-01-01") + duration("P1Y1M1D")返回2016-02-02的日期。 也可以从时间实例中减去持续时间。

duration("PT30S") * 10返回5分钟的持续时间。 也可以将持续时间除以数字。

Mathematical Functions

abs($expr)绝对值。

rand()返回0(包括)到1(不包括),[0,1)范围内的随机数。 返回每个调用的新值。 也可用于选择子集或随机排序。

round($expr)舍入到最接近的整数; ceil()和floor()向上或向下查找下一个整数。

sqrt($expr)平方根。

sign($expr)绝对值。

sin($expr)三角函数还包括cos(),tan(),cot(),asin(),acos(),atan(),atan2()和hasrsin()。 如果没有另外指定,三角函数的所有参数都应该是弧度。

degrees($expr), radians($expr), pi()将弧度转换为度数; 使用radians()作为反向,使用pi()作为π。

log10($expr), log($expr), exp($expr), e()对数基数10,自然对数,e到参数的幂,以及e的值。

String Functions

toString($expression)表达式的字符串表示形式。

replace($original, $search, $replacement)用替换替换所有出现的搜索。 所有参数都必须是表达式。

substring($original, $begin, $subLength)获取字符串的一部分。 subLength参数是可选的。

left($original, $subLength), right($original, $subLength)字符串的第一部分。 字符串的最后一部分。

trim($original), lTrim($original), rTrim($original)修剪所有空格,或左侧或右侧。

toUpper($original), toLower($original)大写和小写。

split($original, $delimiter)将字符串拆分为字符串列表。

reverse($original)反转一个字符串。

size($string)计算字符串中的字符数。

Relationship Functions

type(a_relationship)关系类型的字符串表示形式。

startNode(a_relationship)关系的起始节点。

endNode(a_relationship)关系的结束节点。

id(a_relationship)关系的内部id。

Aggregating Functions

count(*)匹配行的数量。

count(variable)非空值的数量。

count(DISTINCT variable)所有聚合函数也采用DISTINCT运算符,该运算符从值中删除重复项。

collect(n.property)从值列出,忽略null。

sum(n.property)求和数值。 类似的函数是avg(),min(),max()。

percentileDisc(n.property, $percentile)离散百分位数。 连续百分位数是百分位数()。 百分位数参数从0.0到1.0。

stDev(n.property)人口样本的标准差。 对于整个人口使用stDevP()。

INDEX

CREATE INDEX ON :Person(name)在标签Person和property name上创建索引。

MATCH (n:Person) WHERE n.name = $value索引可以自动用于相等比较。 请注意,例如toLower(n.name)= $ value将不使用索引。

MATCH (n:Person) WHERE n.name IN [$value]索引可以自动用于IN列表检查。

MATCH (n:Person) USING INDEX n:Person(name) WHERE n.name = $value当Cypher使用次优索引或应使用多个索引时,可以强制执行索引使用。

DROP INDEX ON :Person(name)删除标签Person和property name上的索引。

CONSTRAINT

CREATE CONSTRAINT ON (p:Person) ASSERT p.name IS UNIQUE在标签Person和属性名称上创建唯一的属性约束。 如果使用已存在的名称更新或创建具有该标签的任何其他节点,则写入操作将失败。 此约束将创建一个附带索引。

DROP CONSTRAINT ON (p:Person) ASSERT p.name IS UNIQUE删除标签Person和property name上的唯一约束和索引。

CREATE CONSTRAINT ON (p:Person) ASSERT exists(p.name)(★)在标签Person和属性名称上创建节点属性存在约束。 如果创建具有该标签的节点而没有名称,或者如果从具有Person标签的现有节点中删除name属性,则写入操作将失败。

DROP CONSTRAINT ON (p:Person) ASSERT exists(p.name)(★)删除标签Person和property name上的node属性存在约束。

CREATE CONSTRAINT ON ()-[l:LIKED]-() ASSERT exists(l.when)(★)在类型LIKED和属性时创建关系属性存在约束。 如果在没有when的情况下创建了与该类型的关系,或者如果从具有LIKED类型的现有关系中删除了when属性,则写入操作将失败。

DROP CONSTRAINT ON ()-[l:LIKED]-() ASSERT exists(l.when)(★)在类型LIKED和属性时删除关系属性存在约束。

CREATE CONSTRAINT ON (p:Person) ASSERT (p.firstname, p.surname) IS NODE KEY(★)在标签Person和properties firstname和surname上创建一个Node Key约束。 如果创建具有该标签的节点而没有firstname和surname,或者两者的组合不唯一,或者如果修改了具有Person标签的现有节点上的firstname和/或surname标签以违反这些约束,则写入 操作将失败。

DROP CONSTRAINT ON (p:Person) ASSERT (p.firstname, p.surname) IS NODE KEY(★)删除标签Person和properties firstname和surname上的Node Key约束。

PS:(★)为Neo4j企业版提供的功能。

Performance

  • 尽可能使用参数而不是文字。 这允许Cypher重用您的查询,而不必解析和构建新的执行计划。
  • 始终为可变长度模式设置上限。 很容易让查询疯狂并错误地触摸图中的所有节点。
  • 仅返回您需要的数据。 避免返回整个节点和关系 - 而是选择所需的数据并仅返回该数据。