MongoDB Vector Search 查询采用 聚合管道 的形式,该管道使用 $vectorSearch 作为第一阶段。本指南介绍了 $vectorSearch 阶段的语法、选项和行为。
注意
MongoDB Vector Search 支持在运行MongoDB v6.0.11 的集群上进行 ANN搜索,v7.0.2 或更高版本,ENN在运行MongoDB v6.0.16 的集群上搜索v7.0.10,v7.3.2,或更高版本。
支持的客户端
您可以使用Atlas用户界面、mongosh 和任何$vectorSearch MongoDB 驱动程序。 运行 查询。
您还可以将MongoDB Vector Search 与通过Atlas CLI创建的本地Atlas部署结合使用。要学习;了解更多信息,请参阅创建本地Atlas部署。
$vectorSearch 仅适用于运行以下 MongoDB 版本的 Atlas 集群:
v 6.0.11
v7.0.2 及更高版本(包括 RC)。
语法
您要搜索的字段必须作为 vectorSearch 索引类型内的MongoDB Vector Search 向量 类型进行索引。
$vectorSearch 管道采用以下原型形式:
{ "$vectorSearch": { "exact": true | false, "filter": {<filter-specification>}, "index": "<index-name>", "limit": <number-of-results>, "numCandidates": <number-of-candidates>, "path": "<field-to-search>", "queryVector": [<array-of-numbers>], "explainOptions": { "traceDocumentIds": [<array-of-documentIDs>] }, "searchNodePreference": { "key": <preference-string> } } }
字段
$vectorSearch 阶段采用包含以下字段的文档:
字段 | 类型 | 必要性 | 说明 |
|---|---|---|---|
| 布尔 | Optional | 如果已省略 该标志指定是运行 ENN 还是 ANN 搜索。值可以是以下值之一:
如果省略,则默认值为 MongoDB Vector Search 支持在运行 ANN 搜索 MongoDB 6.0.11、v7.0.2 或更高版本,ENN搜索在运行MongoDB v6.0.16、v7.0.10,v7.3.2,或更高版本。 要学习;了解有关这些搜索类型的更多信息,请参阅向量搜索类型。 |
| 文档 | Optional | 用于将索引字段用作预过滤器的 MQL 表达式。您可以使用过滤器过滤布尔值、日期、objectId、数值、字符串和 UUID 值,包括这些类型的数组。 要学习;了解MongoDB Vector Search 在过滤中支持哪些MQL操作符,请参阅MongoDB Vector Search 预筛选。 |
| 字符串 | 必需 | 要使用的MongoDB Vector Search索引的名称。 如果索引名称拼写错误或者指定的索引在集群上尚不存在,MongoDB Vector Search 不会返回结果。 |
| 数字 | 必需 | 要在结果中返回的文档数量(仅限 |
| 数字 | 可选的 | 如果 搜索期间要使用的最近邻数量。值必须小于或等于 ( 我们建议您指定一个至少比要返回的文档数( 这种过度请求模式是权衡 ANN 搜索延迟与召回率的推荐方案,建议根据具体数据集规模和查询需求调整此参数。 要了解可能影响此参数的其他变量,请参阅 |
| 字符串 | 必需 | 要搜索的索引向量类型字段。 |
| 数字数组 | 必需 |
要了解有关生成BSON 数组大小必须与字段的索引定义中指定的向量 您必须使用用于嵌入数据的同一模型来嵌入查询。 只要向量子类型相同,您就可以使用全保真向量查询嵌入。这仅适用于子类型为 |
| 文档 | Optional | 在解释 |
explainOptions.traceDocumentIds | 文档ID数组 | 必需 | 文档 |
| 对象 | Optional | 为此查询启用优先路由的文档。如果您为此字段设立了值,则只要该值保持不变,Atlas 就会每次针对同一搜索节点执行此查询,从而覆盖默认查询路由行为。 此文档包含一个键值对,其中 重要: 启用此设置可以提高您的搜索结果的一致性,但不能保证永久的 ACID 一致性保证。对数据集、索引结构、集群拓扑结构或首选节点可用性的更改仍可能导致不一致。 |
向量搜索类型
定义 $vectorSearch 阶段时,可以使用 exact 字段指定运行 近似最近邻 (ANN) 搜索还是 精确最近邻 (ENN) 搜索。
近似最近邻 (ANN) 搜索
对于近似最近邻 (ANN)搜索, MongoDB 向量搜索 会根据向量嵌入在多维空间中的接近度以及所考虑的邻域数量,在您的数据中查找与查询中的向量嵌入最接近的向量嵌入。它使用Hierarchical Navigable Small Worlds算法,找到与查询中的向量嵌入最相似的向量嵌入,而无需扫描每个向量。因此,近似最近邻 (ANN)搜索非常适合查询大型数据集,而无需进行大量过滤器。
注意
ANN搜索的最佳召回率通常被认为是与 9095ENN搜索的结果重叠约 - %,但延迟要低得多。这在准确性和性能之间提供了良好的平衡。要使用MongoDB Vector Search 实现此目的,请在查询时调整 numCandidates 参数。
numCandidates 选择
您必须指定 numCandidates字段才能运行近似最近邻 (ANN)搜索。该字段确定 MongoDB 向量搜索 在搜索过程中考虑的最近邻数量。
我们建议您指定的 numCandidates 数字至少比要返回的文档数量 (limit) 高 20 倍,以提高准确性并减少 精确最近邻 (ENN) 和 近似最近邻 (ANN) 查询结果之间的差异。示例,如果将 limit设立为 5 结果,则可以考虑将 numCandidates 设置为 100 作为点。要学习;了解详情,请参阅如何衡量查询结果的准确性。
这种过度请求模式是在近似最近邻 (ANN) 搜索中平衡延迟和召回的推荐方法。不过,我们建议根据特定数据集大小和查询要求调整 numCandidates 参数。为确保获得准确的结果,请考虑以下变量:
索引大小:较大的集合通常需要更高的
numCandidates值来维持召回率。包含数百万个向量的集合可能需要比包含数千个向量的集合显著更多的候选项。限制值:由于
numCandidates与索引大小高度相关,较低的limit值需要相应较高的numCandidates值以维持召回率。向量量化:量化向量通过牺牲精度来降低存储需求。与全精度向量相比,使用量化向量(
int8或int1子类型)可能需要更高的numCandidates值float32以保持相似的召回率。
精确最近邻 (ENN) 搜索
对于精确最近邻 (ENN)搜索, MongoDB Vector Search 通过计算所有嵌入之间的距离来详尽搜索所有索引的向量嵌入,并为查询中的向量嵌入找到精确最近邻 (ENN)。此操作属于计算密集型任务,可能会对查询延迟负面影响。因此,我们建议对以下使用案例进行 精确最近邻 (ENN) 搜索:
您需要利用针对 ENN 查询得出的理想且精确的结果,来确定 ANN 查询的召回率与准确率。
您希望查询少于 10000 个文档,而不必调整要考虑的最近邻的数量。
您希望在查询中包含选择性的预过滤条件,针对那些少于 5% 的数据满足给定预过滤条件的集合。
如果启用自动量化, MongoDB Vector Search 仅使用全保真向量进行 ENN 查询。
行为
$vectorSearch必须是其所在的任何管道中的第一阶段。
限制
$vectorSearch 不能用于视图定义和后续管道阶段:
| [1] | 您可以将 $vectorSearch 的结果传递给此阶段。 |
MongoDB Vector Search 索引
您必须使用$vectorSearch vectorSearch 类型索引定义中的 阶段对要搜索的字段索引。您可以在MongoDB Vector Search vectorSearch 类型索引定义中对以下类型的字段索引:
要学习;了解有关这些MongoDB Vector Search字段类型的更多信息,请参阅如何为向量搜索的字段创建索引。
MongoDB Vector Search 评分
MongoDB Vector Search 为其返回的每个文档分配一个分数,该分数在 0 到 1 之间的固定范围内(其中 0 表示低相似度,1 表示高相似度)。
该分数根据您在MongoDB Vector Search 索引定义中指定的 similarity 函数计算得出。要进一步学习;了解可供选择的 similarity 选项,请参阅关于相似度函数。
每个返回的文档都包含分数作为元数据。要返回每个文档的分数以及结果设立,请在聚合管道中使用 $project 阶段并将 score 配置为要项目的字段。在 score 字段中,指定值为 vectorSearchScore 的 $meta 表达式。语法如下:
1 db.<collection>.aggregate([ 2 { 3 "$vectorSearch": { 4 <query-syntax> 5 } 6 }, 7 { 8 "$project": { 9 "<field-to-include>": 1, 10 "<field-to-exclude>": 0, 11 "score": { "$meta": "vectorSearchScore" } 12 } 13 } 14 ])
注意
只有在$vectorSearch 管道阶段之后,才能将 vectorSearchScore用作score $meta 表达式。如果您在任何其他查询后使用 vectorSearchScore,则从MongoDB v8.2 开始,MongoDB会日志一条警告。
注意
对数据进行预筛选不会影响MongoDB Vector Search 使用 vectorSearchScore 进行$vectorSearch 查询返回的分数。
MongoDB Vector Search 预过滤
该 $vectorSearchfilter 选项匹配 BSON 布尔值、日期、objectId、数值、字符串和 UUID 值,包括这些类型的数组。
您必须将要用于过滤数据的字段作为 vectorSearch 类型索引定义中的过滤 类型进行索引。过滤数据有助于缩小语义搜索的范围,并确保不会考虑将所有向量进行比较。
MongoDB Vector Search$vectorSearchfilter 支持以下MQL操作符的 选项:
注意
$vectorSearch filter 选项不支持其他查询操作符、聚合管道操作符或MongoDB Search 操作符。
过滤器注意事项
MongoDB Vector Search 支持
$eq的简写形式。在简写形式中,您无需在查询中指定$eq。例如,考虑以下带有
$eq的过滤器:"filter": { "_id": { "$eq": ObjectId("5a9427648b0beebeb69537a5") } 这相当于以下过滤器,它使用
$eq的简写形式:"filter": { "_id": ObjectId("5a9427648b0beebeb69537a5") } 您可以使用
$andMQL 操作符在单个查询中指定过滤器数组。例如,考虑以下预过滤器,用于
genres字段等于Action和year字段值为1999、2000或2001的文档:"filter": { "$and": [ { "genres": "Action" }, { "year": { "$in": [ 1999, 2000, 2001 ] } } ] } 对于模糊搜索、短语匹配、位置过滤器和其他分析文本等高级过滤器功能,请在 阶段使用 vectorSearch
$search操作符。
跨分段执行并行查询
我们建议使用专用搜索节点来隔离向量搜索查询处理。您可能会发现专用搜索节点上的查询性能有所提高。请注意,高 CPU 系统可能会提供更多的性能改进。当MongoDB Vector Search 在搜索节点上运行时, MongoDB Vector Search 会跨数据段并行执行查询。
在许多情况下,查询处理的并行化可以缩短响应时间,例如对大型数据集的查询。在MongoDB Vector Search查询处理期间使用查询内并行机制会占用更多资源,但会缩短每个查询的延迟。
注意
MongoDB Vector Search 不保证每个查询都会同时运行。示例,当排队的并发查询过多时, MongoDB Vector Search 可能会转为单线程执行。
对于同一节点上或不同节点上的相同连续近似最近邻 (ANN)搜索查询,您可能会看到不一致的结果。为了缓解这个问题,请考虑增加 $vectorSearch 查询中 numCandidates 的值,或修改索引定义中 hnswOptions 内的构造参数。但是,由于 近似最近邻 (ANN) 搜索的性质,无法保证完全一致性。
示例
以下查询搜索示例sample_mflix.embedded_movies使用 $vectorSearch 阶段的集合。查询搜索plot_embedding_voyage_3_large字段,其中包含使用 Voyage AI的 voyage-3-large 嵌入模型创建的嵌入。
先决条件
在运行这些示例之前,请执行以下操作:
将示例集合添加到您的 Atlas 集群中。
为集合创建MongoDB Vector Search 搜索索引。有关说明,请参阅创建MongoDB 向量搜索 索引过程,并以所需语言复制基本或过滤器示例的配置。
注意
如果您使用 mongosh,将示例代码中的 queryVector 粘贴到您的终端可能需要一段时间,具体取决于您的设备。
基本 近似最近邻 (ANN) 示例
以下查询使用 $vectorSearch 阶段通过向量嵌入在 plot_embedding_voyage_3_large 字段中搜索 time travel 字符串。它最多考虑 150 个最近邻,并在结果中返回 10 个文档。该查询还指定了一个 $project 阶段以执行以下操作:
在结果中排除
_id字段并仅包含plot和title字段。添加名为
score的字段,以显示结果中的每个文档的向量搜索分数。
筛选的 ANN 示例
以下查询筛选在一月 01, 1955 和 01, 1975 之间上映的电影的文档,然后再对样本向量数据执行语义Atlas Search 。 它使用$and操作符对指定日期执行逻辑AND操作。 然后,它使用向量嵌入string在筛选后的文档中的 plot_embedding_voyage_3_large 字段以查找 150 个最近邻,并在结果中返回 10 个文档。 该查询还指定了一个$project阶段来执行以下操作:
结果中排除
_id字段,仅包含plot、title和year字段。添加名为
score的字段,显示结果中文档的Atlas Vector Search分数。
MongoDB Vector Search 根据介于 1955 和 1975 之间的 year字段值筛选文档。它返回总结了 1955 和 1975 之间上映的电影情节中的儿童冒险经历的文档。
精确最近邻 (ENN) 示例
以下查询使用 $vectorSearch 阶段,通过向量嵌入在 plot_embedding_voyage_3_large 字段中搜索 world war 字符串。它要求完全匹配,并将结果限制在 10 个文档内。该查询还指定了 $project 阶段来执行以下操作:
在结果中排除
_id字段,而仅包含plot、title和year字段。添加名为
score的字段,显示结果中文档的Atlas Vector Search分数。