模式
Cypher® 依赖 模式匹配 来查找数据。模式通常用于 MATCH 语句中,例如
MATCH (m:Movie)<-[:ACTED_IN]-(a:Actor)
模式可以极其复杂,而 @neo4j/cypher-builder 提供了定义这些模式所需的工具。
节点和关系
模式由节点和关系组成。第一步是定义模式中引用的变量。
const person = new Cypher.Node();
const movie = new Cypher.Node();
const actedIn = new Cypher.Relationship();
基础模式
所有模式都以节点开头和结尾。通过使用之前定义的变量,模式可以定义如下
const pattern = new Cypher.Pattern(person, { labels: ["Person"] }).related(actedIn, { type: "ACTED_IN" }).to(movie, { labels: ["Movie"] });
此模式现在可以在任何可以使用模式的地方使用,例如在 MATCH 子句中。
new Cypher.Match(pattern);
MATCH (this0:Person)-[this1:ACTED_IN]->(this2:Movie)
关系方向
默认情况下,模式中的关系被创建为从左到右的模式。在使用 direction 属性在模式中定义关系时,可以更改方向。
const pattern = new Cypher.Pattern(person)
.related(actedIn, { type: "ACTED_IN", direction: "left" })
.to(movie);
这会转换为以下模式
(this0)<-[this1:ACTED_IN]-(this2)
direction 的选项包括
-
right(默认):从左到右 (()-[]→()) 的模式。 -
left:从右到左 (()←[]-()) 的模式。 -
undirected:无向 (()-[]-()) 模式。
移除变量名
模式中的节点和关系变量是可选的,如果不传递变量,它将不会在 Cypher 中呈现。
const pattern = new Cypher.Pattern(person, { labels: ["Person"] }).related({type: "ACTED_IN"}).to({labels: ["Movie"]});
这会转换为
(this0:Person)-[:ACTED_IN]->(:Movie)
移除标签和类型
标签和类型在模式中是可选的。
const pattern = new Cypher.Pattern(person).related(actedIn).to(movie, { labels: ["Movie"] });
(this0)-[this1]->(this1:Movie)
|
标签和类型也可以在 |
属性
模式可能包含用于匹配节点和关系的属性。这些可以使用 properties 参数添加。
const pattern = new Cypher.Pattern(person, {
labels: ["Person"],
properties: { name: new Cypher.Param("Person") },
}).related(actedIn, { type: "ACTED_IN" })
.to(movie, { labels: ["Movie"] });
(this0:Person { name: $param0 })-[this1:ACTED_IN]->(this2:Movie)
properties 参数接受一个对象,其中包含要匹配的属性以及用作模式期望值的参数对象。它可用于节点和关系元素。
高级模式
本节展示如何定义更复杂的模式。
更长的模式
模式可以是任意长度。例如
const user = new Cypher.Node();
const pattern = new Cypher.Pattern({labels: ["Person"]}).related({type: "ACTED_IN"}).to().related({direction: "left"}).to(user, { labels: ["User"] });
(:Person)-[:ACTED_IN]->()<-[]-(this1:User)
循环
模式可能包含循环。为此,您可以重复使用相同的变量。
const actor = new Cypher.Node();
const movie = new Cypher.Node();
const actedIn = new Cypher.Relationship();
const directed = new Cypher.Relationship();
const pattern = new Cypher.Pattern(person, { labels: ["Person"] })
.related(actedIn, { type: "ACTED_IN" })
.to(movie, { labels: ["Movie"] })
.related(directed, { direction: "undirected", type: "DIRECTED" })
.to(actor);
这会转换为
(this0:Person)-[this1:ACTED_IN]->(this2:Movie)-[this3:DIRECTED]-(this0)
请注意模式中的初始节点 (this0) 与最后一个元素中引用的节点相同。这可以匹配既是演员又导演了同一部电影的人。
长度
关系的长度(或跳数)可以使用 length 属性定义。
精确长度
可以通过传递一个数字来定义精确长度。
const pattern = new Cypher.Pattern({}).related(actedIn, { type: "ACTED_IN", length: 3 }).to();
MATCH ()-[this1:ACTED_IN*3]->()
WHERE 谓词
WHERE 子句可用作模式中节点和关系的谓词。
const movie = new Cypher.Node({ labels: ["Movie"] });
new Cypher.Pattern(movie, { labels: ["Movie"] }).where(Cypher.eq(movie.property("title"), new Cypher.Literal("The Matrix")));
(this0:Movie WHERE this0.title = "The Matrix")
标签表达式
通过使用 标签表达式,可以将复杂的标签过滤器作为模式的一部分添加。以下是可用的表达式
-
labelExpr.and -
labelExpr.or -
labelExpr.not -
labelExpr.wildcard
例如:
const movieNode = new Cypher.Node();
const matchQuery = new Cypher.Match(
new Cypher.Pattern(movieNode, {
labels: Cypher.labelExpr.and(Cypher.labelExpr.or("Movie", "Film"), Cypher.labelExpr.not("Show")),
})
).return(movieNode);
MATCH (this0:((Movie|Film)&!Show))
RETURN this0
|
默认情况下,模式中的多个标签使用
|
动态标签和类型
模式中的标签和关系类型可以是动态表达式。要使标签动态化,只需将任何 Cypher 表达式传递给 labels 或 type 即可。这会将表达式包装在 $() 中。
示例 1:使用参数作为节点标签
const query = new Cypher.Match(
new Cypher.Pattern(new Cypher.Node(), {
labels: new Cypher.Param("Movie"),
})
)
MATCH (this0:$($param0))
示例 2:关系上的动态类型
关系类型同理
const query = new Cypher.Match(
new Cypher.Pattern()
.related({
type: new Cypher.Param("ACTED_IN"),
})
.to()
)
MATCH ()-[:$($param1)]->()
示例 3:将标签表达式与动态标签一起使用
const movieLabel = new Cypher.Variable();
const query = new Cypher.With([new Cypher.Literal("Movie"), movieLabel])
.match(
new Cypher.Pattern(new Cypher.Node(), {
labels: Cypher.labelExpr.or(
movieLabel,
Cypher.labelExpr.not(new Cypher.Param("paramLabel"))
),
})
)
WITH "Movie" AS var0
MATCH (this1:($(var0)|!$($param1)))
量化路径模式
量化路径模式 可以使用 Cypher.QuantifiedPath 类来定义。
QuantifiedPath 代表量化模式或普通模式的并集。例如
const m = new Cypher.Node();
const m2 = new Cypher.Node();
const quantifiedPath = new Cypher.QuantifiedPath(
new Cypher.Pattern(m, { labels: ["Movie"], properties: { title: new Cypher.Param("V for Vendetta") } }),
new Cypher.Pattern({ labels: ["Movie"] })
.related({ type: "ACTED_IN" })
.to({ labels: ["Person"] })
.quantifier({ min: 1, max: 2 }),
new Cypher.Pattern(m2, {
labels: ["Movie"],
properties: { title: new Cypher.Param("Something's Gotta Give") },
})
);
const query = new Cypher.Match(quantifiedPath).return(m2);
生成以下 Cypher
MATCH (this0:Movie { title: $param0 })
((:Movie)-[:ACTED_IN]->(:Person)){1,2}
(this1:Movie { title: $param1 })
RETURN this1
请注意,QuantifiedPath 要求至少一个模式具有量词。这可以通过普通 Pattern 类的 .quantifier 方法来完成。此方法将 (:Movie)-[:ACTED_IN]→(:Person) 这样的模式转换为量化模式:(:Movie)-[:ACTED_IN]→(:Person){1,2}。
quantifier 方法接受一个参数,可以是以下之一
-
一个数字,定义精确长度。
-
一个包含可选属性
min,max的对象。 -
字符串
+或*。