()
代表一个匿名的、无特征的节点。如果我们想在别处引用该节点,我们可以添加一个变量,例如:(matrix)
。变量仅限于单个语句。它在另一个语句中可能具有不同的含义或没有含义。()
(matrix)
(:Movie)
(matrix:Movie)
(matrix:Movie {title: 'The Matrix'})
(matrix:Movie {title: 'The Matrix', released: 1997})
-[role]->
-[:ACTED_IN]->
-[role:ACTED_IN]->
-[role:ACTED_IN {roles: ['Neo']}]->
:ACTED_IN
)类似于节点的标签。属性(例如,roles
)完全等同于节点属性。(keanu:Person:Actor {name: 'Keanu Reeves'})-[role:ACTED_IN {roles: ['Neo']}]->(matrix:Movie {title: 'The Matrix'})
acted_in = (:Person)-[:ACTED_IN]->(:Movie)
CREATE (:Movie {title: 'The Matrix', released: 1997})
还可以返回创建的数据
CREATE (a:Person {name: 'Tom Hanks', born: 1956})-[r:ACTED_IN {roles: ['Forrest']}]->(m:Movie {title: 'Forrest Gump', released: 1994})
return a, r, m
# 查找所有标有Movie标签的节点
MATCH (m:Movie)
RETURN m
# 查找一个特定的人
MATCH (p:Person {name: 'Keanu Reeves'})
RETURN p
# 查找一些联系
MATCH (p:Person {name: 'Tom Hanks'})-[r:ACTED_IN]->(m:Movie)
RETURN m.title, r.roles
MATCH (p:Person {name: 'Tom Hanks'})
CREATE (m:Movie {title: 'Cloud Atlas', released: 2012})
CREATE (p)-[r:ACTED_IN {roles: ['Zachry']}]->(m)
RETURN p, r, m
Cpyher中MERGE相当于MATCH或CREATE的组合,它在创建数据之前检查数据是否存在。MERGE允许提供要设置的其他属性ON CREATE。
MERGE (m:Movie {title: 'Cloud Atlas'})
ON CREATE SET m.released = 2012
RETURN m
MERGE
也可以断言关系只创建一次。为此,您必须从先前的模式匹配中传入两个节点。
MATCH (m:Movie {title: 'Cloud Atlas'})
MATCH (p:Person {name: 'Tom Hanks'})
MERGE (p)-[r:ACTED_IN]->(m)
ON CREATE SET r.roles =['Zachry']
RETURN p, r, m
如果您选择只传入前一个子句中的一个节点,则MERGE
提供了一个有趣的功能。然后它只会在给定模式的提供节点的直接邻域内匹配,如果没有找到,则创建它。这对于创建例如树结构非常方便。
CREATE (y:Year {year: 2014})
MERGE (y)<-[:IN_YEAR]-(m10:Month {month: 10})
MERGE (y)<-[:IN_YEAR]-(m11:Month {month: 11})
RETURN y, m10, m11
现在我们将研究过滤结果的选项,只返回我们感兴趣的数据子集。这些过滤条件使用WHERE
子句表示。这个子句允许使用任意数量的布尔表达式和为此谓词,结合AND
,OR
,XOR
和NOT
。最简单的谓词是比较;尤其是平等。
MATCH (m:Movie)
WHERE m.title = 'The Matrix'
RETURN m
相当于
MATCH (m:Movie {title: 'The Matrix'})
RETURN m
WHERE子句还可以是正则表达式匹配、数值比较和查看列表中是否存在某个值
MATCH (p:Person)-[r:ACTED_IN]->(m:Movie)
WHERE p.name =~ 'K.+' OR m.released > 2000 OR 'Neo' IN r.roles
RETURN p, r, m
一个高级用法是模式可以用作谓词。在MATCH
扩展匹配模式的数量和形状的地方,模式谓词限制当前结果集。它只允许满足指定模式的路径通过。正如我们可以预期,采用NOT
只允许传递那些不符合指定的模式的路径。
# 在这里,我们找到演员,因为他们建立了ACTED_IN关系,但随后跳过了DIRECTED任何电影中的那些演员
MATCH (p:Person)-[:ACTED_IN]->(m)
WHERE NOT (p)-[:DIRECTED]->()
RETURN p, m
length(array)
,toInteger('12')
,substring('2014-07-01', 0, 4)
和coalesce(p.nickname, 'n/a')
。expression AS alias
. 随后可以使用别名来引用该列。。MATCH (p:Person)
RETURN
p,
p.name AS name,
toUpper(p.name),
coalesce(p.nickname, 'n/a') AS nickname,
{name: p.name, label: head(labels(p))} AS person
MATCH (n)
RETURN DISTINCT labels(n) AS Labels
RETURN
计算最终结果的子句中。许多常见的聚集功能的支持,例如count
,sum
,avg
,min
,和max
MATCH (:Person)
RETURN count(*) AS people
使用ORDER BY expression [ASC|DESC]
子句进行排序。表达式可以是任何表达式,只要它可以从返回的信息中计算出来。使用ORDER BY expression [ASC|DESC]
子句进行排序。表达式可以是任何表达式,只要它可以从返回的信息中计算出来。
一个非常有用的聚合函数是collect()
,它将所有聚合值收集到一个列表中。这在许多情况下非常有用,因为在聚合时不会丢失任何细节信息。
collect()
非常适合检索典型的父子结构,其中每行返回一个核心实体(parent、root或head)及其所有相关信息,这些信息位于用collect()
. 这意味着无需为每个子行重复父信息,也无需运行n+1
语句来分别检索父行及其子行。创建的列表collect()
可以从使用 Cypher 结果的客户端使用,也可以直接在具有任何列表函数或谓词的语句中使用。
MATCH (m:Movie)<-[:ACTED_IN]-(a:Person)
RETURN m.title AS movie, collect(a.name) AS cast, count(*) AS actors
UNION [ALL]
.MATCH (actor:Person)-[r:ACTED_IN]->(movie:Movie)
RETURN actor.name AS name, type(r) AS type, movie.title AS title
UNION
MATCH (director:Person)-[r:DIRECTED]->(movie:Movie)
RETURN director.name AS name, type(r) AS type, movie.title AS title
相当于
MATCH (actor:Person)-[r:ACTED_IN|DIRECTED]->(movie:Movie)
RETURN actor.name AS name, type(r) AS type, movie.title AS title
在 Cypher 中,可以将语句片段链接在一起,类似于它在数据流管道中的完成方式。每个片段都处理前一个片段的输出,其结果可以输入下一个片段。 只有在WITH
子句中声明的列在后续查询部分中可用。
该WITH
子句用于组合各个部分并声明哪些数据从一个部分流向另一个部分。 WITH
与RETURN
子句类似。不同之处在于该WITH
子句不会完成查询,而是为下一部分准备输入。表达式、聚合、排序和分页的使用方式与RETURN
子句中的使用方式相同。唯一的区别是所有列都必须有别名。
MATCH (person:Person)-[:ACTED_IN]->(m:Movie)
WITH person, count(*) AS appearances, collect(m.title) AS movies
WHERE appearances > 1
RETURN person.name, appearances, movies
在图数据库中使用索引的主要原因是为了找到图遍历的起点。一旦找到该起点,遍历就依赖于图内结构来实现高性能。可以随时添加索引。
# 创建一个索引以加快在数据库中按名称查找演员的速度
CREATE INDEX FOR (a:Actor) ON (a.name)
# 在大多数情况下,查询数据时不需要指定索引,因为将自动使用适当的索引
MATCH (actor:Actor {name: 'Tom Hanks'})
RETURN actor
复合索引是对具有特定标签的所有节点的多个属性的索引。
# 在所有标有Actor和 且同时具有name和born属性的节点上创建一个复合索引
CREATE INDEX FOR (a:Actor) ON (a.name, a.born)
我们可以检查我们的数据库以找出定义了哪些索引。我们通过调用内置过程来做到这一点db.indexes
:
CALL db.indexes
YIELD description, tokenNames, properties, type;
约束用于确保数据符合域的规则。例如:“如果一个节点的标签为Actor
,属性为name
,则 的值name
在所有具有Actor
标签的节点中必须是唯一的”。
为了创建一个约束以确保我们的数据库永远不会包含多个带有标签Movie
和title
属性的节点,我们使用 IS UNIQUE 语法
CREATE CONSTRAINT ON (movie:Movie) ASSERT movie.title IS UNIQUE
我们可以检查我们的数据库以找出定义了哪些约束。我们通过调用内置过程来做到这一点db.constraints
:
CALL db.constraints
MATCH (n:Test) RETURN distinct keys(n)