Neo4j
Cypher
什么是 Cypher?
Cypher 是一种声明式图查询语言,它允许对图进行表达性和高效的查询、更新和管理。它旨在适用于开发人员和运营专业人员。Cypher 设计简单但功能强大;可以轻松表达高度复杂的数据库查询,使您能够专注于您的领域,而不是迷失在数据库访问中。
结构
Cypher 借鉴了 SQL 的结构——查询是使用各种子句构建的。
子句链接在一起,它们在彼此之间提供中间结果集。例如,一个子句中的匹配变量MATCH
将是下一个子句所在的上下文。
以下是一些用于从图中读取的子句示例:
MATCH
:要匹配的图形模式。这是从图表中获取数据的最常用方法。WHERE
: 本身不是一个子句,而是MATCH
,OPTIONAL MATCH
和的一部分WITH
。向模式添加约束,或过滤通过WITH
.RETURN
: 返回什么。
让我们看看MATCH
并RETURN
采取行动。
CREATE (john:Person {name: 'John'})
CREATE (joe:Person {name: 'Joe'})
CREATE (steve:Person {name: 'Steve'})
CREATE (sara:Person {name: 'Sara'})
CREATE (maria:Person {name: 'Maria'})
CREATE (john)-[:FRIEND]->(joe)-[:FRIEND]->(steve)
CREATE (john)-[:FRIEND]->(sara)-[:FRIEND]->(maria)
MATCH (john {name: 'John'})-[:FRIEND]->()-[:FRIEND]->(fof)
RETURN john.name, fof.name
返回结果:
+----------------------+
| john.name | fof.name |
+----------------------+
| "John" | "Maria" |
| "John" | "Steve" |
+----------------------+
2 rows
接下来,我们将添加过滤以设置更多运动部分:
我们获取一个用户名列表,并从该列表中找到具有名称的所有节点,匹配他们的朋友并仅返回那些具有以‘S’开头的‘name’属性的被关注用户。
MATCH (user)-[:FRIEND]->(follower)
WHERE user.name IN ['Joe', 'John', 'Sara', 'Maria', 'Steve'] AND follower.name =~ 'S.*'
RETURN user.name, follower.name
+---------------------------+
| user.name | follower.name |
+---------------------------+
| "John" | "Sara" |
| "Joe" | "Steve" |
+---------------------------+
这些是用于更新图形的子句示例:
CREATE
(和DELETE
):创建(和删除)节点和关系。SET
(和REMOVE
):为属性设置值并在节点上添加标签 usingSET
和 useREMOVE
删除它们。MERGE
:匹配现有的或创建新的节点和模式。这与独特的约束一起特别有用。
Neo4j 数据库和图表
Cypher 查询是针对 Neo4j 数据库执行的,但通常适用于特定的图。重要的是要理解这些术语的含义,以及当图形不是数据库时的确切含义。
数据库管理系统
Neo4j 数据库管理系统能够包含和管理数据库中包含的多个图。客户端应用程序将连接到 DBMS 并针对它打开会话。客户端会话提供对 DBMS 中任何图形的访问。
图形
这是数据库中的数据模型。通常每个数据库中只有一个图,并且许多引用特定图的管理命令使用数据库名称来执行此操作。 在会话中执行的 Cypher 查询可以声明它们适用于哪个图,或使用会话给出的默认值。 在 Neo4j Fabric 中,可以在同一个查询中引用多个图。
数据库
数据库是一种存储和检索机制,用于在磁盘和内存的定义空间中收集数据。
大多数情况下,Cypher 查询是读取或更新查询,这些查询是针对图运行的。还有一些适用于数据库或整个 DBMS 的管理命令。管理命令不能在连接到普通用户数据库的会话中运行,而是需要在连接到系统数据库的会话中运行。
1系统数据库和默认数据库
所有 Neo4j 服务器都包含一个名为 的内置数据库system
,它的行为与所有其他数据库不同。数据库存储系统数据,system
您无法对其执行图形查询。
Neo4j 的全新安装包括两个数据库:
system
上述系统数据库,包含有关 DBMS 和安全配置的元数据。neo4j
默认数据库,使用配置选项命名dbms.default_database=neo4j
。
查询、更新和管理
更新查询的结构
如果您的查询只执行读取,Cypher 在您询问结果之前不会真正匹配模式。在更新查询中,语义是所有读取都将在执行任何写入之前完成。
查询部分是隐式的唯一模式是当您首先读取然后写入时 - 任何其他顺序,您必须明确查询部分。使用WITH
语句分隔部分。 WITH
就像一个事件视界——它是一个计划和该计划的完成执行之间的障碍。
当您想使用聚合数据进行过滤时,您必须将两个阅读查询部分链接在一起——第一个进行聚合,第二个过滤来自第一个的结果。
MATCH (n {name: 'John'})-[:FRIEND]-(friend)
WITH n, count(friend) AS friendsCount
WHERE friendsCount > 3
RETURN n, friendsCount
使用WITH
,您可以指定聚合发生的方式,并且聚合必须在 Cypher 开始过滤之前完成。
这是一个更新图表的示例,将聚合数据写入图表:
MATCH (n {name: 'John'})-[:FRIEND]-(friend)
WITH n, count(friend) AS friendsCount
SET n.friendsCount = friendsCount
RETURN n.friendsCount
返回数据
任何查询都可以返回数据。如果查询只读取,它必须返回数据。如果读取查询不返回任何数据,则它没有任何用途,因此不是有效的 Cypher 查询。更新图表的查询不必返回任何内容,但它们可以。
在查询的所有部分之后是最后一个RETURN
子句。 RETURN
不是任何查询部分的一部分——它是查询末尾的句点符号。该RETURN
条款附带三个子条款:SKIP
/LIMIT
和ORDER BY
.
如果您从刚刚删除它们的查询中返回节点或关系 - 请注意,您持有的指针不再有效。
Cypher路径匹配
Neo4j Cypher利用关系同构进行路径匹配,是减少结果集大小和防止无限遍历的一种非常有效的方法。
在 Neo4j 中,所有的关系都有一个方向。但是,您可以在查询时拥有无向关系的概念。
在可变长度模式表达式的情况下,进行约束检查尤为重要,否则可能会找到无限数量的结果记录。
为了更好地理解这一点,让我们考虑一些替代方案:
- 同态:路径匹配没有限制。
- 节点同构:对于每个路径匹配记录,不能多次返回同一节点。
- 关系同构:对于每个路径匹配记录,不能多次返回相同的关系。Cypher 利用关系同构进行路径匹配。
- 同态
该图仅由两个节点(a)
和组成(b)
,由一个关系连接,(a:Node)-[r:R]->(b:Node)
。
如果查询正在寻找长度路径n
并且不关心方向,n
则将返回一个长度路径,一遍又一遍地重复两个节点。
例如,查找所有具有 5 个关系的路径并且不关心关系方向:
MATCH p = ()-[*5]-()
RETURN nodes(p)
如果使用同态,这将返回两个结果记录[a,b,a,b,a,b]
,以及[b,a,b,a,b,a]
。
- 节点同构
在另一个双节点示例中,例如(a:Node)-[r:R]->(b:Node)
; 使用节点同构约束只能找到长度为 1 的路径。
该图仅由两个节点(a)
和组成(b)
,由一个关系连接,(a:Node)-[r:R]->(b:Node)
。
MATCH p = ()-[*1]-()
RETURN nodes(p)
如果使用节点同构,这将返回两个结果记录[a, b]
,以及[b, a]
。
- 关系同构
在另一个双节点示例中,例如(a:Node)-[r:R]->(b:Node)
; 使用关系同构约束只能找到长度为 1 的路径。
该图仅由两个节点(a)
和组成(b)
,由一个关系连接,(a:Node)-[r:R]->(b:Node)
。
MATCH p = ()-[*1]-()
RETURN nodes(p)
这将返回两个结果记录[a, b]
,以及[b, a]
.
- Cypher 路径匹配示例
Cypher 利用关系同构进行路径匹配。
寻找用户的朋友的朋友不应该返回说用户。
为了证明这一点,让我们创建一些节点和关系:
查询1,创建数据。
CREATE
(adam:User {name: 'Adam'}),
(pernilla:User {name: 'Pernilla'}),
(david:User {name: 'David'}),
(adam)-[:FRIEND]->(pernilla),
(pernilla)-[:FRIEND]->(david)
Nodes created: 3
Relationships created: 2
Properties set: 3
现在让我们寻找Adam朋友的朋友:
查询 2,亚当的朋友的朋友。
MATCH (user:User {name: 'Adam'})-[r1:FRIEND]-()-[r2:FRIEND]-(friend_of_a_friend)
RETURN friend_of_a_friend.name AS fofName
+---------+
| fofName |
+---------+
| "David" |
+---------+
在此查询中,Cypher 确保不返回模式关系r1
并r2
指向相同图形关系的匹配项。
然而,这并不总是需要的。如果查询应该返回用户,则可以将匹配分布在多个MATCH
子句中,如下所示:
查询 3,多个 MATCH 子句。
MATCH (user:User {name: 'Adam'})-[r1:FRIEND]-(friend)
MATCH (friend)-[r2:FRIEND]-(friend_of_a_friend)
RETURN friend_of_a_friend.name AS fofName
+---------+
| fofName |
+---------+
| "David" |
| "Adam" |
+---------+
请注意,虽然下面的查询 4看起来与查询 3相似,但它实际上等同于查询 2。
查询 4,相当于查询 2。
MATCH
(user:User {name: 'Adam'})-[r1:FRIEND]-(friend),
(friend)-[r2:FRIEND]-(friend_of_a_friend)
RETURN friend_of_a_friend.name AS fofName
在这里,MATCH
子句有一个带有两个路径的模式,而前面的查询有两个不同的模式。
+---------+
| fofName |
+---------+
| "David" |
+---------+
Syntax句法
值和类型
属性类型
Integer、Float、String、Boolean、Point、Date、Time、LocalTime、DateTime、LocalDateTime 和 Duration。
结构类型
Node, Relationship, and Path(节点、关系和路径)
复合类型
List和Map。
命名规则和建议
命名规则
- 字母字符:
- 名称应以字母字符开头。
- 这包括“非英语”字符,例如
å
,ä
,ö
等ü
。
- 数字:
- 名称不应以数字开头。
- 举例来说,
1first
不允许,而first1
允许。
- 符号:
- 名称不应包含符号,下划线除外,如 中
my_variable
,或$
作为表示参数的第一个字符,如 给出$myParam
。
- 名称不应包含符号,下划线除外,如 中
- 长度:
- 可以很长,最多为
65535
(2^16 - 1
) 或65534
字符,具体取决于 Neo4j 的版本。
- 可以很长,最多为
- 区分大小写:
- 名称区分大小写,因此 ,
:PERSON
和:Person
是:person
三个不同的标签,n
和N
是两个不同的变量。
- 名称区分大小写,因此 ,
- 空白字符:
- 前导和尾随空白字符将被自动删除。例如,
MATCH ( a ) RETURN a
等价于MATCH (a) RETURN a
。
- 前导和尾随空白字符将被自动删除。例如,
非字母字符,包括数字、符号和空格字符,可以在名称中使用,但必须使用反引号进行转义。例如:^n
、1first
、$$n
和my variable has spaces
。数据库名称是一个例外,可能包含点而不需要转义。例如:命名数据库foo.bar.baz
是完全有效的。
范围和命名空间规则
- 节点标签、关系类型和属性名称可以重用名称。
- 以下查询(带有
a
标签、类型和属性名称)是有效的:CREATE (a:a {a: 'a'})-[r:a]->(b:a {a: 'a'})
.
- 以下查询(带有
- 节点和关系的变量不得在同一查询范围内重复使用名称。
- 以下查询无效,因为节点和关系都具有名称
a
:CREATE (a)-[a]->(b)
。
- 以下查询无效,因为节点和关系都具有名称
表达式
一般表达
Cypher 中的大多数表达式计算null
其内部表达式是否为null
. 值得注意的例外是运算符IS NULL
和IS NOT NULL
.
Cypher 中的表达式可以是:
- 十进制(整数或浮点数)文字:
13
,40000
,3.14
- 科学记数法的十进制(整数或浮点数)文字:
6.022E23
. - 十六进制整数文字(以 开头
0x
):0x13af
,0xFC3A9
,0x66eff
. - 八进制整数文字(以
0o
or开头0
):0o1372
,02127
,0o5671
. - 字符串文字:
'Hello'
,"World"
. - 布尔文字:
true
,false
. - 一个变量:
n
,x
,rel
,myFancyVariable
,A name with weird stuff in it[]!
. - 一个属性:
n.prop
,x.prop
,rel.thisProperty
,myFancyVariable.
(weird property name)``. - 动态属性:
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)
. - 一个聚合函数:
avg(x.prop)
,count(*)
. - 路径模式:
(a)-[r]->(b)
,(a)-[r]-(b)
,(a)--(b)
,(a)-->()<--(b)
. - 运算符应用程序:
1 + 2
,3 < 4
. - 谓词表达式是返回真或假的表达式:
a.prop = 'Hello'
,length(p) > 10
,a.name IS NOT NULL
. - 存在子查询是返回 true 或 false: 的表达式
EXISTS { MATCH (n)-[r]→(p) WHERE p.name = 'Sven' }
。 - 一个正则表达式:
a.name =~ 'Tim.*'
. - 区分大小写的字符串匹配表达式:
a.surname STARTS WITH 'Sven'
,a.surname ENDS WITH 'son'
或a.surname CONTAINS 'son'
. - 一个
CASE
表达。
关于字符串字面量的注意事项
CASE
表达式
通用条件表达式可以使用CASE
构造来表达。Cypher中存在两种变体CASE
:简单形式,允许将表达式与多个值进行比较,以及通用形式,允许表达多个条件语句。
如果您想在后续子句或语句中使用结果,则 CASE 只能用作 RETURN 或 WITH 的一部分。
**简单CASE
形式:将表达式与多个值进行比较
计算表达式,并按顺序与WHEN
子句进行比较,直到找到匹配项。如果未找到匹配项,ELSE
则返回子句中的表达式。但是,如果没有ELSE
case 并且没有找到匹配项,null
则会返回。
CASE test
WHEN value THEN result
[WHEN ...]
[ELSE default]
END
MATCH (n)
RETURN
CASE n.eyes
WHEN 'blue' THEN 1
WHEN 'brown' THEN 2
ELSE 3
END AS result
**通用CASE
形式:允许表达多个条件
谓词按顺序计算,直到true
找到一个值,并使用结果值。如果未找到匹配项,ELSE
则返回子句中的表达式。但是,如果没有ELSE
大小写且未找到匹配项,null
则将返回。
CASE
WHEN predicate THEN result
[WHEN ...]
[ELSE default]
END
MATCH (n)
RETURN
CASE
WHEN n.eyes = 'blue' THEN 1
WHEN n.age < 40 THEN 2
ELSE 3
END AS result
**区分何时使用简单形式和通用CASE
形式
由于两种形式的语法非常相似,有时可能一开始就不清楚使用哪种形式。我们通过以下查询来说明这种情况,其中有一个期望age_10_years_ago
是-1
if n.age
is null
:
MATCH (n)
RETURN n.name,
CASE n.age
WHEN n.age IS NULL THEN -1
ELSE n.age - 10
END AS age_10_years_ago
但是,由于此查询是使用简单CASE
形式编写的,而不是age_10_years_ago
针对-1
名为 的节点Daniel
,它是null
. n.age
这是因为在和之间进行了比较n.age IS NULL
。由于n.age IS NULL
是布尔值,并且n.age
是整数值,因此WHEN n.age IS NULL THEN -1
永远不会采用分支。这导致ELSE n.age - 10
分支被取而代之,返回null
.
正确的查询,如预期的那样,由以下通用CASE
形式给出:
MATCH (n)
RETURN n.name,
CASE
WHEN n.age IS NULL THEN -1
ELSE n.age - 10
END AS age_10_years_ago
**CASE
在随后的子句或语句中使用结果
您可以使用 的结果CASE
来设置节点或关系的属性。例如,您可以为表达式选择的节点设置属性,而不是直接指定节点:
MATCH (n)
WITH n,
CASE n.eyes
WHEN 'blue' THEN 1
WHEN 'brown' THEN 2
ELSE 3
END AS colourCode
SET n.colourCode = colourCode
变量
当您引用模式或查询的某些部分时,您可以通过命名它们来实现。您给不同部分的名称称为变量。
在这个例子中:
MATCH (n)-->(b)
RETURN b
变量是n
和b
。
保留关键字
保留关键字是在 Cypher 中具有特殊含义的词。保留关键字的列表按从中提取它们的类别进行分组。除此之外,还有许多关键字保留供将来使用。
在以下情况下,不允许将保留关键字用作标识符:
- 变量
- 函数名称
- 参数
1. Clauses
CALL
CREATE
DELETE
DETACH
EXISTS
FOREACH
LOAD
MATCH
MERGE
OPTIONAL
REMOVE
RETURN
SET
START
UNION
UNWIND
WITH
2. Subclauses
LIMIT
ORDER
SKIP
WHERE
YIELD
3. Modifiers
ASC
ASCENDING
ASSERT
BY
CSV
DESC
DESCENDING
ON
4. Expressions
ALL
CASE
ELSE
END
THEN
WHEN
5. Operators
AND
AS
CONTAINS
DISTINCT
ENDS
IN
IS
NOT
OR
STARTS
XOR
6. Schema
CONSTRAINT
CREATE
DROP
EXISTS
INDEX
NODE
KEY
UNIQUE
7. Hints
INDEX
JOIN
PERIODIC
COMMIT
SCAN
USING
8. Literals
false
null
true
9. Reserved for future use
ADD
DO
FOR
MANDATORY
OF
REQUIRE
SCALAR
Comments注释
注释以双斜杠 ( ) 开头//
并一直到行尾。评论不会执行,它们是供人类阅读的。
Parameters参数
Operators操作
Pattern模式
模式和模式匹配是 Cypher 的核心,因此要有效使用 Cypher 需要对模式有很好的理解。
使用模式,您可以描述您正在寻找的数据的形状。例如,在MATCH
子句中,您使用模式描述形状,Cypher 将找出如何为您获取该数据。
该模式使用一种非常类似于通常在白板上绘制属性图数据形状的形式来描述数据:通常用圆圈(表示节点)和它们之间的箭头来表示关系。
模式出现在 Cypher 中的多个位置:在MATCH
,CREATE
和MERGE
子句中,以及在模式表达式中。
- 节点模式
可以在模式中描述的最简单的“形状”是节点。使用一对括号来描述节点,并且通常被赋予一个名称。例如:
(a)
这个简单的模式描述了一个节点,并使用变量命名该节点a
。****
- 相关节点的模式
更强大的构造是描述多个节点和它们之间的关系的模式。Cypher 模式通过在两个节点之间使用箭头来描述关系。例如:
(a)-->(b)
此模式描述了一个非常简单的数据形状:两个节点,以及从一个节点到另一个节点的单一关系。在这个例子中,两个节点都分别命名为a
和b
,关系是“有向的”:从a
到b
。
这种描述节点和关系的方式可以扩展到覆盖任意数量的节点和它们之间的关系,例如:
(a)-->(b)<--(c)
这样一系列连接的节点和关系称为“路径”。
请注意,仅当需要再次引用同一节点时,才需要在这些模式中命名节点,无论是在模式的后期还是在 Cypher 查询的其他地方。如果这不是必需的,则可以省略名称,如下所示:
(a)-->()<--(c)
- 标签图案
除了简单地描述模式中节点的形状外,还可以描述属性。模式中可以描述的最简单的属性是节点必须具有的标签。例如:
(a:User)-->(b)
还可以描述具有多个标签的节点:
(a:User:Admin)-->(b)
- 指定属性
节点和关系是图中的基本结构。Neo4j 使用这两个属性来支持更丰富的模型。
属性可以使用 map-construct 以模式表示:围绕多个键-表达式对的花括号,用逗号分隔。例如,具有两个属性的节点看起来像:
(a {name: 'Andy', sport: 'Brazilian Ju-Jitsu'})
与期望的关系由下式给出:
(a)-[{blocked: false}]->(b)
当属性出现在模式中时,它们会为数据的形状添加额外的约束。在CREATE
子句的情况下,将在新创建的节点和关系中设置属性。在MERGE
子句的情况下,属性将用作任何现有数据必须具有的形状的附加约束(指定的属性必须与图中的任何现有数据完全匹配)。如果没有找到匹配的数据,则MERGE
行为类似CREATE
,并将在新创建的节点和关系中设置属性。
请注意,提供给的模式CREATE
可能使用单个参数来指定属性,例如:CREATE (node $paramName)
. 这对于其他子句中使用的模式是不可能的,因为 Cypher 需要在编译查询时知道属性名称,以便可以有效地进行匹配。
- 关系模式
描述关系的最简单方法是使用两个节点之间的箭头,如前面的示例所示。使用这种技术,您可以描述应该存在的关系及其方向性。如果不关心关系的方向,可以省略箭头,例如:
(a)--(b)
与节点一样,关系也可以被命名。在这种情况下,使用一对方括号来分隔箭头,并将变量放置在它们之间。例如:
(a)-[r]->(b)
就像节点上的标签一样,关系也可以有类型。要描述与特定类型的关系,您可以按如下方式指定:
(a)-[r:REL_TYPE]->(b)
与标签不同,关系只能有一种类型。但是,如果我们想描述一些数据,使得关系可以具有一组类型中的任何一种,那么它们都可以在模式中列出,用管道符号分隔它们,|
如下所示:
(a)-[r:TYPE1|TYPE2]->(b)
请注意,这种形式的模式只能用于描述现有数据(即,当使用带有MATCH
或作为表达式的模式时)。它不适用于CREATE
or MERGE
,因为不可能创建具有多种类型的关系。
与节点一样,关系的名称总是可以省略,例如:
(a)-[:REL_TYPE]->(b)
- 变长模式匹配
不是使用模式中的许多节点和关系描述的序列来描述长路径,而是可以通过在模式的关系描述中指定长度来描述许多关系(和中间节点)。例如:
(a)-[*2]->(b)
这描述了三个节点和两个关系的图,都在一个路径中(长度为 2 的路径)。这相当于:
(a)-->()-->(b)
还可以指定长度范围:这种关系模式称为“可变长度关系”。例如:
(a)-[*3..5]->(b)
最小长度为 3,最大长度为 5。它描述了一个由 4 个节点和 3 个关系、5 个节点和 4 个关系或 6 个节点和 5 个关系组成的图,所有这些都在一条路径中连接在一起。
任何一个边界都可以省略。例如,要描述长度为 3 或更多的路径,请使用:
(a)-[*3..]->(b)
要描述长度为 5 或更短的路径,请使用:
(a)-[*..5]->(b)
省略两个边界等效于指定最小值 1,允许描述任何正长度的路径:
(a)-[*]->(b)
作为一个简单的例子,让我们看下面的图表和查询:
MATCH (me)-[:KNOWS*1..2]-(remote_friend)
WHERE me.name = 'Filipa'
RETURN remote_friend.name
remote_friend.name
"Dilshad"
"Anders"
此查询在图形中查找形状符合模式的数据:特别是一个节点(具有名称属性‘Filipa’),然后是KNOWS
一两跳之外的相关节点。这是寻找一级和二级朋友的典型例子。
- 分配给路径变量
如上所述,一系列连接的节点和关系称为“路径”。Cypher 允许使用标识符命名路径,例如:
p = (a)-[*3..5]->(b)
您可以在MATCH
,CREATE
和中执行此操作MERGE
,但在将模式用作表达式时则不行。
Temporal (Date/Time) values
Lists
Maps
Working with null
Clauses从句
MATCH
OPTIONAL MATCH
OPTIONAL MATCH
将模式与您的图形数据库匹配,就像这样MATCH
做一样。不同之处在于,如果没有找到匹配项,OPTIONAL MATCH
将使用 anull
来表示模式的缺失部分。OPTIONAL MATCH
可以被认为是 SQL 中外连接的 Cypher 等价物。
RETURN
WITH
- 使用
WITH
,您可以在将输出传递到以下查询部分之前对其进行操作。可以对结果集中的条目的形状和/或数量进行操作。一种常见用法WITH
是限制传递给其他MATCH
子句的条目数。通过组合ORDER BY
和LIMIT
,可以通过某些标准获得前 X 个条目,然后从图中引入额外的数据。
- 使用
UNWIND
- 使用
UNWIND
,您可以将任何列表转换回单独的行。这些列表可以是传入的参数、先前collect
编辑的结果或其他列表表达式。unwind 的一种常见用法是创建不同的列表。另一种方法是从提供给查询的参数列表中创建数据。UNWIND
要求您为内部值指定一个新名称。
- 使用
WHERE
ORDER BY
SKIP
- 通过使用
SKIP
,结果集将从顶部开始修剪。请注意,除非查询指定ORDER BY
子句,否则不保证结果的顺序。SKIP
接受任何计算结果为正整数的表达式 - 但是该表达式不能引用节点或关系。 - 要返回结果的子集,从第四个结果开始,使用以下语法:
MATCH (n) RETURN n.name ORDER BY n.name SKIP 3
- 返回中间两行
MATCH (n) RETURN n.name ORDER BY n.name SKIP 1 LIMIT 2
- 通过使用
LIMIT
CREATE
DELETE
SET
REMOVE
FOREACH
- 列表和路径是 Cypher 中的关键概念。该
FOREACH
子句可用于更新数据,例如对路径中的元素或聚合创建的列表执行更新命令。 - 括号内的变量上下文与
FOREACH
括号外的上下文是分开的。这意味着如果您CREATE
是 a 中的节点变量FOREACH
,您将无法在 foreach 语句之外使用它,除非您匹配找到它。 - 在
FOREACH
括号内,您可以执行任何更新命令 -SET
、REMOVE
、CREATE
、MERGE
、DELETE
和FOREACH
。 - 如果要为
MATCH
列表中的每个元素执行附加操作,则该[UNWIND](<https://neo4j.com/docs/cypher-manual/current/clauses/unwind/>)
子句将是更合适的命令。
MATCH p=(start)-[*]->(finish) WHERE start.name = 'A' AND finish.name = 'D' FOREACH (n IN nodes(p) | SET n.marked = true)
- 列表和路径是 Cypher 中的关键概念。该
MERGE
CALL {} (subquery)
- 类似于函数
CALL procedure
UNION
USE
LOAD CSV
- 从 CSV 文件导入数据,要将数据从 CSV 文件导入 Neo4j,您可以使用
LOAD CSV
将数据放入查询中。然后使用 Cypher 的正常更新子句将其写入数据库。
artists.csv:
1,ABBA,1992 2,Roxette,1986 3,Europe,1979 4,The Cardigans,1992
LOAD CSV FROM 'file:///artists.csv' AS line CREATE (:Artist {name: line[1], year: toInteger(line[2])})
- Import data from a CSV file containing headers
artists-with-headers.csv:
Id,Name,Year 1,ABBA,1992 2,Roxette,1986 3,Europe,1979 4,The Cardigans,1992
LOAD CSV WITH HEADERS FROM 'file:///artists-with-headers.csv' AS line CREATE (:Artist {name: line.Name, year: toInteger(line.Year)})
- 使用自定义字段分隔符从 CSV 文件导入数据
artists-fieldterminator.csv:
1;ABBA;1992 2;Roxette;1986 3;Europe;1979 4;The Cardigans;1992
LOAD CSV FROM 'file:///artists-fieldterminator.csv' AS line FIELDTERMINATOR ';' CREATE (:Artist {name: line[1], year: toInteger(line[2])})
- 导入大量数据
如果 CSV 文件包含大量行(接近数十万或数百万),
USING PERIODIC COMMIT
可用于指示 Neo4j 在多行后执行提交。这减少了事务状态的内存开销。默认情况下,提交每 1000 行发生一次。USING PERIODIC COMMIT LOAD CSV FROM 'file:///artists.csv' AS line CREATE (:Artist {name: line[1], year: toInteger(line[2])})
- 设置周期性提交的速率
USING PERIODIC COMMIT 500 LOAD CSV FROM 'file:///artists.csv' AS line CREATE (:Artist {name: line[1], year: toInteger(line[2])})
- 将 linenumber() 与 LOAD CSV 一起使用
LOAD CSV FROM 'file:///artists.csv' AS line RETURN linenumber() AS number, line
- 将 file() 与 LOAD CSV 一起使用
LOAD CSV FROM 'file:///artists.csv' AS line RETURN DISTINCT file() AS path
- 从 CSV 文件导入数据,要将数据从 CSV 文件导入 Neo4j,您可以使用
SHOW FUNCTIONS
SHOW PROCEDURES
SHOW TRANSACTIONS