SEARCH仅限 Cypher 25Neo4j 2026.01 引入
SEARCH 子句本身不是一个独立的子句,而是用于 MATCH 和 OPTIONAL MATCH 子句内的子句,用于基于近似最近邻 (ANN) 向量搜索为其模式添加约束。要使用 SEARCH 子句,必须首先创建向量索引。
SEARCH 子句语法
SEARCH 子句具有以下语法:
[OPTIONAL] MATCH pattern
SEARCH binding_variable IN (
VECTOR INDEX index_name
FOR query_vector
[WHERE ...]
LIMIT top_k
) [SCORE AS score_alias]
SEARCH 子句通过仅返回由 SEARCH 子句描述的 ANN 向量搜索结果中包含的节点或关系,来约束外层 MATCH 或 OPTIONAL MATCH 中的 pattern(模式)。下面简要介绍了语法中的不同部分:
-
binding_variable(绑定变量)必须是来自外层MATCH或OPTIONAL MATCH子句的pattern中的节点或关系变量。 -
index_name(索引名称)必须是一个标识符,与 Neo4j 数据库中现有向量索引的名称相匹配。如果binding_variable引用的是节点,则向量索引必须是节点向量索引;如果binding_variable引用的是关系,则必须是关系向量索引。 -
query_vector(查询向量)可以是任何计算结果为VECTOR或LIST<INTEGER NOT NULL | FLOAT NOT NULL>的表达式,例如字面量、参数或属性。SEARCH子句根据query_vector与这些节点或关系的相应属性之间的相似性,返回节点或关系的邻域。 -
可选的
WHERE子句将过滤器应用于向量索引,它是标准 Cypher®WHERE子句的受限版本。有关更多信息,请参阅带过滤器的向量搜索谓词。 -
LIMIT子句设置由SEARCH子句返回的近似最近邻节点或关系的数量。top_k必须是INTEGER NOT NULL类型,且在区间0 <= top_k <= 2147483647内 [1]。 -
可选的
SCORE子句使得SEARCH子句除了返回节点或关系本身外,还返回每个节点或关系的相似度得分。在结果中,相似度得分列将命名为score_alias。 -
SEARCH子句对外层MATCH或OPTIONAL MATCH子句允许的pattern施加了一些限制。有关更多信息,请参阅SEARCH 子句的限制。
示例图和向量索引
以下图表用于下方的示例
要重建该图,请在空的 Neo4j 数据库中运行以下查询
CREATE (:Movie {title: 'Aladdin', releaseDate: date('1992-11-08'), rating: 8.0}),
(:Movie {title: 'Cinderella', embedding: vector([1, 3, 4], 3, INTEGER), releaseDate: date('1950-02-15'), rating: 7.3}),
(:Movie:Favorite {title: 'Frozen', embedding: [1, 3, 3], releaseDate: date('2013-11-10'), rating: 7.4}),
(:Movie {title: 'Lilo & Stitch', embedding: vector([1, 1, 3], 3, INTEGER), releaseDate: date('2002-06-16'), rating: 7.4}),
(:Movie:Favorite {title: 'Lion King', embedding: vector([2, 5, 2], 3, INTEGER), releaseDate: date('1994-06-12'), rating: 8.5}),
(:Movie:Favorite {title: 'Mulan', embedding: [2, 3, 3], releaseDate: date('1998-06-05'), rating: 7.7}),
(:Movie {title: 'Snow White', embedding: vector([1, 2, 3], 3, INTEGER), releaseDate: date('1937-12-21'), rating: 7.6})
示例图中的每个节点都代表一部电影,并具有标题、发行日期和评分属性。大多数节点还具有一个名为 embedding 的 VECTOR 属性,它是电影情节的向量表示。在现实世界的示例中,这些向量嵌入通常由专有或开源的嵌入生成器生成,并具有例如 768 或 1536 的维度,但为简单起见,此示例数据集使用 3 维的向量嵌入。
这些示例在 embedding 属性上使用名为 moviePlots 的向量索引,并将 releaseDate 和 rating 作为附加过滤属性。此类向量索引可以通过以下 Cypher 查询创建:
CREATE VECTOR INDEX moviePlots IF NOT EXISTS
FOR (m:Movie) ON m.embedding
WITH [m.releaseDate, m.rating]
OPTIONS {
indexConfig: {
`vector.similarity_function`: 'cosine',
`vector.dimensions`: 3,
`vector.quantization.enabled`: false
}
}
有关创建向量索引的更多信息,请参阅创建向量索引。
基本向量搜索
查找最相似的节点
在我们的示例数据集中,标题为 Snow White 的电影具有嵌入 vector([1, 2, 3], 3, INTEGER)。要查找与 Snow White 最相似的 4 部电影,您可以运行几个不同的带有 SEARCH 子句的 Cypher 查询。
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR vector([1, 2, 3], 3, INTEGER)
LIMIT 4
)
RETURN movie.title AS title
| 标题 |
|---|
|
|
|
|
|
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR [1, 2, 3]
LIMIT 4
)
RETURN movie.title AS title
| 标题 |
|---|
|
|
|
|
|
{
snowWhiteEmbedding: vector([1, 2, 3], 3, INTEGER)
}
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR $snowWhiteEmbedding
LIMIT 4
)
RETURN movie.title AS title
| 标题 |
|---|
|
|
|
|
|
MATCH (snowWhite:Movie {title: 'Snow White'})
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR snowWhite.embedding
LIMIT 4
)
RETURN movie.title AS title
| 标题 |
|---|
|
|
|
|
|
上述所有四个查询返回相同的结果。电影节点按相似度递减的顺序返回。Snow White 与其自身最相似,而 Mulan 是与 Snow White 第四相似的电影。电影 Lilo & Stitch 和 Lion King 不会被返回,因为它们不在最相似的前 4 部电影之列;而电影 Aladdin 没有 embedding 属性,因此向量索引完全不考虑它。
|
上述 |
查找带得分的最相似节点
要返回与 Snow White 最相似的四部电影及其相似度得分,您可以在 SEARCH 子句中包含可选的 SCORE 子句。
MATCH (snowWhite:Movie {title: 'Snow White'})
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR snowWhite.embedding
LIMIT 4
) SCORE AS similarityScore
RETURN movie.title AS title, similarityScore
| 标题 | similarityScore |
|---|---|
|
|
|
|
|
|
|
|
|
|
相似度得分类型为 FLOAT NOT NULL,范围在 0.0 和 1.0 之间。得分越接近 1.0,索引的 embedding 属性与查询向量的相似度就越高。电影 Snow White 的相似度得分为 1.0,因为它的 embedding 属性与查询向量完全一致。
相似度得分是使用创建向量索引时选择的相似度函数计算的,默认为余弦相似度。有关相似度函数的更多信息,请参阅余弦和欧几里得相似度函数。
MATCH 模式中的额外谓词
MATCH 或 OPTIONAL MATCH 中的模式可以对带有绑定变量的节点或关系具有标签和属性谓词。
MATCH (movie:Movie&Favorite)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR vector([1, 2, 3], 3, INTEGER)
LIMIT 4
)
RETURN movie.title AS title
| 标题 |
|---|
|
|
|
|
标签谓词充当向量搜索的后过滤步骤。即使标题为 |
MATCH (movie:Movie {releaseDate: date('2013-11-10')})
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR vector([1, 2, 3], 3, INTEGER)
LIMIT 4
)
RETURN movie.title AS title
| 标题 |
|---|
|
|
带过滤器的向量搜索
MATCH 或 OPTIONAL MATCH 子句既可以有 WHERE 子句,也可以有 SEARCH 子句。无论它们的顺序如何,WHERE 子句都将充当向量搜索的后过滤步骤,进一步筛选结果。
以下任一查询都会先找到与 Snow White 最相似的四部电影,然后将结果筛选为仅 1990 年之后发行的电影。
MATCH (movie:Movie)
WHERE movie.releaseDate > date('1990')
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR vector([1, 2, 3], 3, INTEGER)
LIMIT 4
)
RETURN movie.title AS title, movie.releaseDate.year AS year
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR vector([1, 2, 3], 3, INTEGER)
LIMIT 4
)
WHERE movie.releaseDate > date('1990')
RETURN movie.title AS title, movie.releaseDate.year AS year
| 标题 | year |
|---|---|
|
|
|
|
|
|
通常,最好在执行向量搜索的同时进行过滤(即索引内过滤),而不是作为后过滤步骤。这可以通过带过滤器的向量搜索来实现,其中 WHERE 是 SEARCH 子句的子句,而不是外层 MATCH 或 OPTIONAL MATCH 子句的子句。
要查找与 Snow White 最相似且于 1990 年后发行的四部电影,请使用以下查询:
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR vector([1, 2, 3], 3, INTEGER)
WHERE movie.releaseDate > date('1990')
LIMIT 4
)
RETURN movie.title AS title, movie.releaseDate.year AS year
| 标题 | year |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
当使用带过滤器的向量搜索时,向量搜索会持续进行,直到找到符合要求的数量且同时也满足其他谓词的结果。相比之下,在 |
结合使用带过滤器的向量搜索和后过滤
可以将带过滤器的向量搜索与普通的 WHERE 子句结合使用。以下查询查找与 Snow White 最相似且于 1990 年后发行的四部电影,然后进行后过滤,丢弃任何评级低于 7.5 的结果。
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR vector([1, 2, 3], 3, INTEGER)
WHERE movie.releaseDate > date('1990')
LIMIT 4
)
WHERE movie.rating > 7.5
RETURN movie.title AS title, movie.releaseDate.year AS year, movie.rating AS rating
| 标题 | year | rating |
|---|---|---|
|
|
|
|
|
|
|
||
带过滤器的向量搜索的谓词
用于执行带过滤器的向量搜索的可选 WHERE 子句是标准 Cypher WHERE 子句的受限版本,仅允许特定类型的谓词。谓词必须是属性谓词或多个中间用 AND 连接的属性谓词。
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR vector([1, 2, 3], 3, INTEGER)
WHERE movie.releaseDate > date('1948') AND date('2010') > movie.releaseDate
LIMIT 4
)
RETURN movie.title AS title, movie.releaseDate.year AS year
| 标题 | year |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
上述查询中的 |
MATCH (snowWhite:Movie {title:"Snow White"})
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR snowWhite.embedding
WHERE movie.releaseDate < date('2000') AND movie.rating >= snowWhite.rating
LIMIT 4
)
RETURN movie.title AS title, movie.releaseDate.year AS year, movie.rating AS rating
| 标题 | year | rating |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
||
|
如果 |
属性谓词中的变量必须与 SEARCH 子句中的绑定变量相同。
MATCH (m: Movie {name: "Snow White"})
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR vector([1, 2, 3], 3, INTEGER)
WHERE m.rating > 8
LIMIT 4
)
RETURN movie.title AS title
42I74: 错误: 语法错误或访问规则违规 - 带过滤器的向量搜索变量错误。向量搜索过滤器属性谓词中的变量 42001:错误:语法错误或访问规则冲突 - 无效语法 |
属性谓词中的所有属性都必须在创建向量索引时被添加为用于过滤的附加属性。
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR vector([1, 2, 3], 3, INTEGER)
WHERE movie.rating > 8 AND movie.title > "L"
LIMIT 4
)
RETURN movie.title AS title, movie.rating AS rating
22ND3: 错误: 数据异常 - 带过滤器的向量搜索属性错误。属性 |
有关 WHERE 谓词的进一步限制,请参阅WHERE 谓词的限制。
关于向量搜索的更多信息
使用不同维度的查询向量
如果查询向量的维度与配置的向量索引维度不同,则查询将失败。
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR vector([1, 2], 2, INTEGER)
LIMIT 4
)
RETURN movie.title AS title
51N65: 错误: 系统配置或操作异常 - 向量索引维度不匹配。向量索引 |
|
如果向量索引没有配置维度,则查询成功。但是,如果索引中没有与查询向量维度相同的向量,则查询结果将为空。因此,建议在创建向量索引时配置 |
使用计算结果为 null 的查询向量
如果查询向量的计算结果为 null(例如因为它引用了不存在的属性),则 MATCH 内的 SEARCH 子句不返回任何结果。
MATCH (snowWhite:Movie {title: 'Snow White'})
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR snowWhite.prop
LIMIT 4
)
RETURN movie.title AS title
| 标题 |
|---|
|
如果带有计算结果为 null 的查询向量的 SEARCH 子句位于 OPTIONAL MATCH 子句中,则它根据常规 OPTIONAL MATCH 语义返回 null。
MATCH (snowWhite:Movie {title: 'Snow White'})
OPTIONAL MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR snowWhite.prop
LIMIT 4
)
RETURN movie.title AS title
| 标题 |
|---|
|
|
SEARCH 子句的限制
下表列出了 SEARCH 子句的一些过去和现在的限制。如果适用,还列出了解除限制的版本。
SEARCH 子句对外层 MATCH 或 OPTIONAL MATCH 子句的模式施加了限制。
| 限制 | 不允许的示例 | 解除限制版本 |
|---|---|---|
模式不能有多个绑定变量。 |
|
|
模式不能对绑定变量以外的元素设置谓词。 |
|
|
模式长度不能超过一个关系跳数。 |
|
|
模式不能有多个部分。 |
|
|
模式不能有除 |
|
用于执行带过滤器的向量搜索的可选 WHERE 子句是标准 Cypher WHERE 子句的受限版本,仅允许特定类型的属性谓词。
| 限制 | 不允许的示例 | 解除限制版本 |
|---|---|---|
谓词中的比较运算符不能是 |
|
|
谓词不能包含除 |
|
|
谓词不能包含列表运算符。 |
|
|
谓词不能包含字符串运算符。 |
|
|
谓词不能包含类型谓词表达式。 |
|
|
谓词中的表达式不能是 |
|
|
谓词中的表达式不能是 |
|
|
谓词中的表达式不能是 |
|
|
谓词中的表达式不允许引用绑定变量。 |
|
|
谓词不能在同一方向上对同一属性包含多个属性谓词。 |
|
|
谓词不能对同一属性包含多个属性谓词,其中一个是相等性,另一个是范围谓词。 |
|
|
2. NOT 允许用于布尔属性。例如,鉴于 seen 在创建向量索引时已被添加为用于过滤的附加属性,WHERE NOT movie.seen 是允许的,并且内部将重写为 WHERE movie.seen = false。 | ||
| 限制 | 解除限制版本 |
|---|---|
与其他索引命令(如 |
|
Integer.MAX_VALUE。