此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Data Commons 3.4.5! |
向量搜索
随着生成式 AI 的兴起,Vector 数据库在数据库领域获得了强大的吸引力。 这些数据库能够高效存储和查询高维向量,使其非常适合语义搜索、推荐系统和自然语言理解等任务。
向量搜索是一种通过比较向量表示形式(也称为嵌入向量)来检索语义相似数据的技术,而不是依赖传统的完全匹配查询。 这种方法支持智能的上下文感知应用程序,而不仅仅是基于关键字的检索。
在 Spring Data 的上下文中,向量搜索为构建智能、上下文感知的应用程序开辟了新的可能性,尤其是在自然语言处理、推荐系统和生成式 AI 等领域。 通过使用熟悉的存储库抽象对基于向量的查询进行建模,Spring Data 允许开发人员将基于相似性的支持向量的数据库与 Spring Data 编程模型的简单性和一致性无缝集成。
向量模型
为了以类型安全和惯用的方式支持向量搜索, Spring Data 引入了以下核心抽象:
Vector
这Vector
type 表示 n 维数字嵌入,通常由嵌入模型生成。
在 Spring Data 中,它被定义为围绕浮点数数组的轻量级包装器,以确保不变性和一致性。
此类型可用作搜索查询的输入,或用作域实体上的属性以存储关联的向量表示。
Vector vector = Vector.of(0.23f, 0.11f, 0.77f);
用Vector
在你的域模型中,不再需要使用原始数组或数字列表,提供了一种类型更安全、更富有表现力的方式来处理向量数据。
这种抽象还允许与各种矢量数据库和库轻松集成。
它还允许实现特定于供应商的优化,例如不映射到标准浮点 (float
和double
自 IEEE 754 起)表示形式。
域对象可以具有 vector 属性,该属性可用于相似性搜索。
请考虑以下示例:
将 vector 与域对象相关联会导致 vector 作为实体生命周期的一部分被加载和存储,这可能会在检索和持久化作上带来额外的开销。 |
搜索结果
这SearchResult<T>
type 封装向量相似性查询的结果。
它包括匹配的域对象和相关性分数,该分数指示它与查询向量的匹配程度。
这种抽象提供了一种结构化的方式来处理结果排名,并使开发人员能够轻松处理数据及其上下文相关性。
在此示例中,searchByCountryAndEmbeddingNear
method 返回一个SearchResults<Comment>
object,其中包含SearchResult<Comment>
实例。
每个结果都包含匹配的Comment
实体及其相关性分数。
相关性分数是一个数值,指示匹配向量与查询向量的对齐程度。 根据分数是代表距离还是相似性,分数越高可能意味着匹配越接近或越远。
用于计算此分数的评分函数可能因基础数据库、索引或输入参数而异。
Score、Similarity 和 Scoring 函数
这Score
type 包含一个数值,指示搜索结果的相关性。
它可用于根据结果与查询向量的相似性对结果进行排名。
这Score
type 通常是一个浮点数,其解释(越高越好或越低越好)取决于所使用的特定相似性函数。
分数是向量搜索的副产品,不是成功搜索作所必需的。
分数值不是域模型的一部分,因此最好表示为带外数据。
通常,Score 是通过ScoringFunction
.
用于计算此分数的实际评分函数可能取决于基础数据库,并且可以从搜索索引或输入参数中获得。
Spring Data 支持为常用函数声明常量,例如:
- 欧几里得距离
-
计算 n 维空间中涉及平方差和平方根的直线距离。
- 余弦相似度
-
测量两个向量之间的角度,首先计算点积,然后通过除以它们的长度的乘积来归一化其结果。
- 点积
-
计算元素乘法之和。
相似性函数的选择会影响搜索的性能和语义,并且通常由所使用的基础数据库或索引决定。 Spring Data 采用数据库的原生评分功能以及分数是否可用于限制结果。
向量搜索方法
向量搜索方法在存储库中使用与标准 Spring Data 查询方法相同的约定进行定义。
这些方法返回SearchResults<T>
并需要一个Vector
参数来定义查询向量。
实际实现取决于底层数据存储的实际内部结构及其围绕向量搜索的功能。
如果您不熟悉 Spring Data 存储库,请务必熟悉存储库定义和查询方法的基础知识。 |
通常,您可以选择使用两种方法声明搜索方法:
-
查询派生
-
声明基于字符串的查询
Vector Search 方法必须声明Vector
参数来定义查询向量。
派生搜索方法
派生的搜索方法使用方法的名称来派生查询。 Vector Search 在声明搜索方法时,支持使用以下关键字运行 Vector 搜索:
逻辑关键字 | 关键字表达式 |
---|---|
|
|
|
|
派生的搜索方法通常更易于阅读和维护,因为它们依赖于方法名称来表达查询意图。
但是,派生的搜索方法需要声明Score
,Range<Score>
或ScoreFunction
作为Near
/Within
keyword 来按分数限制搜索结果。
带注释的搜索方法
带注释的方法提供对查询语义和参数的完全控制。 与派生方法不同,它们不依赖于方法名称约定。
通过对实际查询的更多控制, Spring Data 可以对查询及其参数做出更少的假设。
例如Similarity
规范化使用查询中的本机 Score 函数将给定的相似性规范化为 Score 谓词值,反之亦然。
如果带注释的查询没有定义例如分数,则返回的SearchResult<T>
将为零。
排序
默认情况下,搜索结果根据其分数进行排序。
您可以使用Sort
参数:
Sort
在 仓库搜索方法interface CommentRepository extends Repository<Comment, String> {
SearchResults<Comment> searchByEmbeddingNearOrderByCountry(Vector vector, Score score);
SearchResults<Comment> searchByEmbeddingWithin(Vector vector, Score score, Sort sort);
}
请注意,自定义排序不允许将分数表示为排序标准。 您只能引用域属性。