您可以使用 vectorSearch 类型对字段进行索引以运行 $vectorSearch 查询。您可以为要查询的向量嵌入定义索引,以及为任何您希望用于预过滤数据的任何其他字段定义索引。过滤数据有助于缩小语义搜索范围,并确保在比较时(例如在多租户环境中)不考虑某些向量嵌入。
您可以使用Atlas用户界面、 Atlas管理API、 Atlas CLI、mongosh 或支持的MongoDB驱动程序来创建MongoDB Vector Search索引。
注意
您不能使用已弃用的 knnBeta 操作符来查询使用 vectorSearch 类型索引定义索引的字段。
Considerations
在 vectorSearch 类型索引定义中,您可以仅使用单个元素对数组索引。您无法对文档数组内的嵌入字段或对象数组内的嵌入字段索引。您可以使用点表示法对文档内的嵌入字段索引。不能在同一索引定义中对同一嵌入字段进行多次索引。
在对嵌入索引之前,我们建议您将嵌入转换为子类型为 float32、int1 或 int8 的 BSON BinData 向量,以便在集群中高效存储。要学习;了解更多信息,请参阅如何将嵌入转换为BSON向量。
使用MongoDB Vector Search 索引时, Atlas 集群的空闲节点上的资源消耗可能会增加。这是由根本的mongot进程造成的,该进程执行MongoDB Vector Search 的各种基本操作。空闲节点上的 CPU 利用率可能因索引的数量、复杂性和大小而异。
要了解有关索引大小注意事项的更多信息,请参阅索引向量的内存需求。
如果对为其定义MongoDB Vector Search索引的集合进行更改,最新数据可能无法立即用于查询。但是,mongot 会监控变更流并更新存储的数据副本,从而使MongoDB Vector Search 索引最终一致。您可以在Atlas用户界面中查看索引 Documents 的数量,以验证对集合的更改是否反映在索引中。
或者,您可以在将新文档添加到集合后创建新索引,并等待索引变为可查询状态。您还可以实现类似于以下的轮询逻辑,以确保索引在尝试使用之前已准备好进行查询。
例子
console.log("Polling to check if the index is ready. This may take up to a minute.") let isQueryable = false; while (!isQueryable) { const cursor = collection.listSearchIndexes(); for await (const index of cursor) { if (index.name === result) { if (index.queryable) { console.log(`${result} is ready for querying.`); isQueryable = true; } else { await new Promise(resolve => setTimeout(resolve, 5000)); } } } }
支持的客户端
您可以通过Atlas用户界面、mongosh、 Atlas CLI、 Atlas管理API和以下MongoDB驱动程序:创建和管理MongoDB Vector Search 索引:
语法
以下语法定义了 vectorSearch 索引类型:
1 { 2 "fields":[ 3 { 4 "type": "vector", 5 "path": "<field-to-index>", 6 "numDimensions": <number-of-dimensions>, 7 "similarity": "euclidean | cosine | dotProduct", 8 "quantization": "none | scalar | binary", 9 "hnswOptions": { 10 "maxEdges": <number-of-connected-neighbors>, 11 "numEdgeCandidates": <number-of-nearest-neighbors> 12 } 13 }, 14 { 15 "type": "filter", 16 "path": "<field-to-index>" 17 }, 18 ... 19 ] 20 }
MongoDB Vector Search 索引字段
MongoDB Vector Search索引定义包含以下字段:
选项 | 类型 | 必要性 | 用途 |
|---|---|---|---|
| 字段定义文档的数组 | 必需 | 要索引的向量和过滤字段的定义,每个文档一个定义。每个字段定义文档都为要索引的字段指定
|
fields.type | 字符串 | 必需 | 用于为
要学习;了解更多信息,请参阅关于 |
fields.path | 字符串 | 必需 | 要为其创建索引的字段名称。对于嵌套字段,使用点表示法来指定嵌入式字段的路径。 |
fields.numDimensions | Int | 必需 | MongoDB Vector Search 在索引时和查询时实施的向量维度数。只能为 对于索引量化向量或 BinData,您可以指定以下值之一:
您选择的嵌入模型决定了向量嵌入的维数,某些模型对于输出的维数有多个选项。要学习;了解更多信息,请参阅选择创建嵌入的方法。 |
fields.similarity | 字符串 | 必需 | 用于搜索前 K 个最近邻域的向量相似度函数。只能为 您可以指定以下值之一:
|
fields.quantization | 字符串 | Optional | 向量的自动向量量化类型。仅当嵌入是 您可以指定以下值之一:
|
fields.hnswOptions | 对象 | Optional | 用于构建 Hierarchical Navigable Small Worlds(分层可导航小世界) 图的参数。如果未指定,将使用 重要提示:这是作为“预览”功能提供的。修改默认值可能会对MongoDB Vector Search索引和查询产生负面影响。 |
fields.hnswOptions.maxEdges | Int | Optional | 在分层可导航小世界图中,一个节点最多可以拥有的边(或连接)数量。值可以在 数字越大,召回率(搜索结果的准确性)越高,因为图表的连接性更好。但是,由于每个图表节点要评估的邻居数量较多,这会降低查询速度;由于每个节点存储更多连接,因此会增加Hierarchical Navigable Small Worlds图表的内存;并且会减慢索引,因为MongoDB Vector Search 会评估更多邻居并进行调整添加到图表中的每个新节点。 |
fields.hnswOptions.numEdgeCandidates | Int | Optional | 类似于查询时的 较高的数值可以生成具有高质量连接的图,从而提升搜索质量(召回率),但也可能对查询延迟产生负面影响。 |
关于 vector 类型
索引定义的 vector 字段必须包含以下类型之一的数字数组:
您必须在 fields 数组中将向量字段作为 vector 类型进行索引。
以下语法定义了 vector 字段类型:
1 { 2 "fields":[ 3 { 4 "type": "vector", 5 "path": <field-to-index>, 6 "numDimensions": <number-of-dimensions>, 7 "similarity": "euclidean | cosine | dotProduct", 8 "quantization": "none | scalar | binary", 9 "hnswOptions": { 10 "maxEdges": <number-of-connected-neighbors>, 11 "numEdgeCandidates": <number-of-nearest-neighbors> 12 } 13 }, 14 ... 15 ] 16 }
关于相似度函数
MongoDB Vector Search 支持以下相似度函数:
euclidean— 测量向量两端之间的距离。您可以通过该值根据不同的维度衡量相似性。要了解更多信息,请参阅欧几里得。cosine— 根据向量之间的角度测量相似度。 通过该值,您可以衡量不按幅度缩放的相似度。 不能将零幅度向量与cosine一起使用。 要衡量余弦相似度,我们建议您对向量进行归一化并改用dotProduct。dotProduct- 与cosine类似的测量计算,但考虑了向量的幅度。如果对幅度进行归一化,则cosine和dotProduct在衡量相似性方面几乎相同。要使用
dotProduct,您必须在索引时和查询时将向量标准化为单位长度。
下表显示了各种类型的相似度函数:
向量嵌入类型 | euclidean | cosine | dotProduct |
|---|---|---|---|
| √ | ||
| √ | √ | √ |
| √ | √ | √ |
| √ | √ | √ |
用于向量摄取。
用于自动标量或二进制量化。
每个相似度函数的公式如下:
对于 cosine, MongoDB Vector Search 使用以下算法对分数进行归一化:
score = (1 + cosine(v1,v2)) / 2
该算法通过考虑文档向量 (
v1) 和查询向量 (v2) 的相似度分数(范围为 [-1,1])对分数进行归一化。MongoDB Vector Search 会将1添加到相似度分数,以将分数规范化在 [0,2]范围内,然后除以2以确保其值介于0和1之间。
对于 dotProduct, MongoDB Vector Search 使用以下算法对分数进行归一化:
score = (1 + dotProduct(v1,v2)) / 2
该算法通过考虑文档向量 (
v1) 和查询向量 (v2) 的相似度分数(范围为 [-1,1])对分数进行归一化。MongoDB Vector Search 会将1添加到相似度分数,以将分数规范化在 [0,2]范围内,然后除以2以确保其值介于0和1之间。
对于 euclidean 相似度, MongoDB Vector Search 使用以下算法对分数进行归一化,以确保其值介于 0 和 1 之间:
score = 1 / (1 + euclidean(v1,v2))
该算法通过计算欧几里得距离对分数进行归一化,欧几里得距离是文档向量 (
v1) 和查询向量 (v2) 之间的距离,其范围为 [0,∞]。然后, MongoDB Vector Search 将1添加到该距离,然后将1除以结果以确保该值介于0和1之间,从而将距离转换为相似度分数。
为获得最佳性能,请检查您的嵌入模型,以确定哪个相似度函数适合嵌入模型的培训进程。 如果没有任何指导,请从 dotProduct 开始。 将 fields.similarity 设置为 dotProduct 值可让您根据角度和幅度有效地衡量相似性。 dotProduct 比 cosine 消耗的计算资源更少,并且在向量为单位长度时非常高效。 但是,如果您的向量未标准化,请评估 euclidean 距离和 cosine 相似度的示例查询结果中的相似度分数,以确定哪一个对应于合理的结果。
关于 filter 类型
您可以选择对附加字段建立索引,以便预先过滤您的数据。您可以使用过滤器过滤布尔值、日期、objectId、数值、字符串和 UUID 值,包括这些类型的数组。过滤数据有助于缩小语义搜索的范围,并确保不会考虑将所有向量进行比较。它减少了用于运行相似性比较的文档数量,从而可以降低查询延迟并提高搜索结果的准确性。
您必须使用 fields大量内的 filter 类型为要过滤的字段索引。
以下语法定义了 filter 字段类型:
1 { 2 "fields":[ 3 { 4 "type": "vector", 5 ... 6 }, 7 { 8 "type": "filter", 9 "path": "<field-to-index>" 10 }, 11 ... 12 ] 13 }
注意
对数据进行预过滤不会影响MongoDB Vector Search 使用 vectorSearchScore 进行$vectorSearch查询返回的分数。
创建MongoDB Vector Search 索引
您可以通过Atlas用户界面、 Atlas API 、 索引 Atlas CLI、8192mongosh ,或支持的MongoDB驱动程序。
先决条件
要创建MongoDB Vector Search索引,您的集群必须满足以下先决条件:
MongoDB 版本
6.0.11、7.0.2或更高版本要为其创建MongoDB Vector Search索引的集合
必需的访问权限
您需要 Project Data Access Admin 或更高角色才能创建和管理MongoDB Vector Search 索引。
索引限制
您创建的内容不能超过:
M0集群上的 3 索引(无论类型是search还是vector)。针对 Flex 集群的 10 个索引。
我们建议您在单个 M10+集群上创建不超过 2、500 个搜索索引。
步骤
注意
该过程包括 sample_mflix数据库中 embedded_movies集合的索引定义示例。如果将示例数据加载到集群上并为此集合创建示例MongoDB Vector Search 索引,则可以对此集合运行示例$vectorSearch 查询。要学习;了解有关可以运行的示例查询的详情,请参阅 $vectorSearch 示例。
查看MongoDB Vector Search 索引
您可以从Atlas用户界面、 Atlas管理API、 Atlas CLI、mongosh 或支持的MongoDB驱动程序。查看所有集合的MongoDB Vector Search 索引。
必需的访问权限
您需要 Project Search Index Editor 或更高角色才能查看MongoDB Vector Search 索引。
步骤
编辑MongoDB Vector Search 索引
您可以从Atlas用户界面、 Atlas管理API、 Atlas CLI、mongosh 或支持的MongoDB驱动程序更改现有MongoDB Vector Search索引的索引定义。您无法重命名索引或更改索引类型。如果需要更改索引名称或类型,则必须创建新索引并删除旧索引。
重要
编辑索引后, MongoDB Vector Search 会重建索引。重建索引时,您可以使用旧索引定义继续运行向量搜索查询。当索引完成重建后,旧索引将被自动替换。此进程类似于MongoDB Search 索引。要学习;了解更多信息,请参阅创建和更新MongoDB搜索索引。
必需的访问权限
您必须具有 Project Search Index Editor 或更高角色才能编辑MongoDB Vector Search索引。
步骤
删除MongoDB Vector Search 索引
您可以随时从Atlas用户界面、 Atlas管理API、 Atlas CLI、mongosh 或支持的MongoDB驱动程序。中删除MongoDB Vector Search索引。
必需的访问权限
您必须具有 Project Search Index Editor 或更高角色才能删除MongoDB Vector Search索引。
步骤
索引状态
创建MongoDB Vector Search索引时,Status 列会显示集群主节点 (primary node in the replica set)节点上索引的当前状态。单击状态下方的 View status details 链接,可查看集群所有节点上索引的状态。
当 Status 列显示为 Active时,索引已准备就绪,可供使用。在其他状态下,对索引的查询可能会返回不完整的结果。
状态 | 说明 |
|---|---|
未启动 | Atlas 尚未开始构建索引。 |
初始化同步(Resumable Initial Sync) | Atlas 正在构建索引或在编辑后重新构建索引。当该索引处于以下状态时:
|
活跃的 | 索引已准备就绪。 |
正在恢复 | |
已失败 | Atlas无法构建索引。使用 View status details 模式窗口中的错误来解决问题。要学习;了解更多信息,请参阅修复问题。 |
正在删除 | Atlas 正在从集群节点中删除索引。 |
当 Atlas 构建索引时以及构建完成后,Documents 列会显示已完成索引的文档的百分比和数量。该列还会显示集合中的文档总数。