向量索引已成为构建现代应用的强大工具。它使您能够对高维数据执行快速高效的 相似度搜索 ,这些高维数据通常被称为 向量嵌入 。这一能力现已无缝集成至 MongoDB,开发者可以直接在数据库中构建复杂功能。
本文将以实践为导向,手把手带您在 MongoDB 中设置并使用向量索引。从创建第一个索引到运行复杂查询,我们将逐步讲解。您还将学习最佳实践,并通过一个电商商店的产品推荐系统这一真实案例来加深理解。
什么是向量索引?
从本质上讲, 向量索引 是一种组织向量嵌入以加速相似度搜索的技术。与作用于标量值(如数字或字符串)的传统索引不同,向量索引针对在多维空间中查找“相邻”向量进行了优化。
向量嵌入是对复杂数据(包括文本、图像和音频)的数值化表示。例如,一段产品描述可以被转换为一个向量,类似产品的向量会在空间中彼此更接近。这种距离上的接近性使以下应用成为可能:
语义搜索: 基于查询的含义查找产品,而非仅仅匹配关键词。
推荐系统: 根据用户偏好为其推荐产品或内容。
图像识别: 从大型数据库中识别相似图像。
在 MongoDB 中设置向量索引
开始之前,您需要一个 MongoDB Atlas 集群。向量搜索是云原生功能。您可以在 MongoDB Atlas 或免费的 Community edition 中试用该功能。本文将使用 MongoDB Atlas。
步骤 1:创建 MongoDB Atlas 集群
在 MongoDB Atlas 中创建一个新集群。免费 M0 层足以用于测试。
步骤 2:创建集合并插入数据
首先,使用 MongoDB Shell( mongosh )或您偏好的驱动程序连接到集群。然后创建名为 products 的新集合,并插入包含向量字段的文档。每个文档应表示一个产品,并包含一个 embedding 字段,用于存放该产品的向量表示。
下面是一个更完整的示例,包含三个不同的产品文档,每个都带有一个随机生成的向量,以演示数据可能的结构。在真实场景中,您会将其替换为由 AI 模型生成的嵌入。
db.products.insertMany([
{
"name": "Wireless Noise-Canceling Headphones",
"category": "Electronics",
"description": "Premium over-ear headphones with active noise cancellation and a 30-hour battery life.",
"price": 249.99,
"embedding": [0.012, 0.054, 0.089, -0.031, 0.067, 0.021, -0.045, 0.098, 0.011, -0.076, 0.033, -0.015, -0.087, 0.059, 0.009, 0.042]
},
{
"name": "Smart Coffee Maker",
"category": "Home Goods",
"description": "Programmable coffee machine that can be controlled from your smartphone. Brews up to 12 cups.",
"price": 129.99,
"embedding": [0.056, 0.023, 0.011, 0.078, -0.029, 0.041, 0.087, -0.019, 0.065, 0.002, -0.093, 0.018, 0.057, -0.041, 0.022, 0.064]
},
{
"name": "Ultra-light Backpack",
"category": "Travel",
"description": "Durable and lightweight backpack with multiple compartments, perfect for hiking or daily commutes.",
"price": 79.99,
"embedding": [-0.072, 0.034, 0.019, 0.068, -0.055, 0.081, 0.004, -0.025, 0.039, 0.016, -0.044, 0.062, 0.008, 0.071, -0.013, 0.053]
}
]);技术支持
每个文档都包含 name 、 category 、 description 和 price ,以及关键的 embedding 字段。 该 embedding 是一个固定大小的数字数组,表示产品描述的语义含义。该数组的大小,即 维度 ,取决于用于生成嵌入的模型。在本示例中,维度为 128。
我们将在这些数据之上构建向量索引,以实现 语义搜索 和 产品推荐 。
步骤 3:创建向量索引
当集合中已有带嵌入的数据后,下一步就是创建向量索引。该索引对于实现快速高效的相似度搜索至关重要。下面的命令使用 createSearchIndex 在 embedding 字段上构建向量索引。
db.products.createSearchIndex({
"name": "vector_index",
"definition": {
"mappings": {
"dynamic": true,
"fields": [
{
"type": "vector",
"path": "embedding",
"numDimensions": 128,
"similarity": "cosine"
}
]
},
}
});技术支持
理解配置
索引配置定义在 definition 对象的 fields 数组内。该结构是 MongoDB Atlas 组织向量以实现高速检索的蓝图。
向量索引的核心参数包括:
path :指定文档中存放向量数组的字段名,本例为 "embedding" 。
numDimensions :这是最关键的参数, 必须与 您的嵌入模型产生的向量数组元素个数完全一致(例如 128、768、1536)。
similarity :定义搜索时用于计算两个向量“接近程度”的数学度量。
cosine 通常推荐用于语义搜索,因为它测量向量之间的夹角,侧重语义方向。
其他选项包括 euclidean (直线距离)和 dotProduct 。
可选性能参数
对于高级 性能调优 ,MongoDB Atlas 允许您指定可选参数以优化存储与内存:
quantization :用于压缩向量,可显著减少索引大小和内存占用。
scalar 或 binary 可用于量化向量,在略微牺牲召回率的前提下,显著提升存储效率与速度。
执行向量搜索查询
索引构建完成后,您可以使用 $vectorSearch 聚合 阶段来执行相似度查询。
让我们查找与某个查询向量最相似的产品。该查询通常由用户的搜索输入生成。
// A sample query vector, generated from a user's search for "wireless audio device"
const queryVector = [0.11, 0.22, 0.33, ...];
db.products.aggregate([
{
"$vectorSearch": {
"queryVector": queryVector,
"path": "embedding",
"numCandidates": 100, // Number of documents to scan
"limit": 5 // Number of results to return
}
},
{
"$project": {
"name": 1,
"description": 1,
"_id": 0
}
}
]);技术支持
queryVector :要搜索的向量。
path :包含向量嵌入的字段名。
numCandidates :在索引中扫描的候选文档数量。数值越高,准确性越好,但延迟也会增加。
limit :返回的结果数量上限。
可选的 $project 阶段有助于整理输出,并从结果中排除向量数据。
向量索引的最佳实践
在为最佳性能调优向量索引时,您需要在 准确性 与 速度 之间取得平衡。关键在于根据您的特定数据集和性能目标来调整索引参数。
选择合适的相似度度量
度量的选择至关重要,因为它定义了两个向量的“相似”程度。您可以参考 MongoDB 文档 以进一步了解这些字段。
cosine :最适合语义相似性,尤其是文本。它测量向量间的夹角,忽略长度。这对向量长度无实际意义的模型至关重要。
euclidean :测量两向量之间的直线距离。如果向量的大小(长度)对其含义很重要(例如某些数据类型中更大值表示更强特征),可使用该度量。
dotProduct :计算两个向量的点积。该度量常用于推荐系统。当向量嵌入被归一化为长度 1 时,点积在功能上等同于余弦相似度。
管理嵌入维度
参数 dimensions 至关重要,并且 必须与 您的嵌入模型的输出完全一致。一个常见错误是选择与模型输出不匹配的数字。维度更高的模型能捕捉更多细节,但索引会更大,查询可能变慢。务必查阅模型文档以确认其维度(例如 OpenAI 的 text-embedding-ada-002 输出 1536 维)。
索引调优
参数 numCandidates 和 numLists 对于在 速度 与 准确性 之间取得平衡至关重要。一个不错的经验法则是从较低的 numCandidates 开始,逐步增加,直到达到满意的准确度。对于 ivf 索引,您也可以尝试不同的 numLists ,以找到最适合您数据集的平衡点。
示例用例:构建简单推荐系统
让我们将这些概念应用到一个实践示例:电商产品推荐系统。
步骤 1:存储带有嵌入的产品数据
首先,我们将存储产品名称、类别以及各自的向量嵌入。嵌入可以根据产品描述或特性生成。
db.products.insertMany([
{
"name": "Smart Speaker",
"category": "Electronics",
"embedding": [0.8, 0.9, 0.1, ...]
},
{
"name": "Wireless Earbuds",
"category": "Electronics",
"embedding": [0.7, 0.8, 0.2, ...]
},
{
"name": "Leather Wallet",
"category": "Fashion",
"embedding": [0.1, 0.2, 0.9, ...]
}
]);技术支持
步骤 2:在 embedding 上创建向量索引
db.products.createSearchIndex({
"name": "vector_index",
"definition": {
"mappings": {
"fields": [
{
"type": "vector",
"path": "embedding", // The field containing the vectors
"numDimensions": 128, // The correct field name is 'numDimensions'
"similarity": "cosine" // The correct field name is 'similarity'
// Index algorithm (like HNSW) is managed automatically by Atlas
}
]
}
}
});技术支持
步骤 3:查询相似产品
现在,让我们查找与 Smart Speaker 相似的产品。我们将使用 Smart Speaker 的嵌入作为查询向量。
const smartSpeakerEmbedding = [0.8, 0.9, 0.1, ...];
db.products.aggregate([
{
"$vectorSearch": {
"queryVector": smartSpeakerEmbedding,
"path": "embedding",
"numCandidates": 50,
"limit": 3
}
},
{
"$project": {
"name": 1,
"category": 1,
"_id": 0
}
}
]);技术支持
此查询将返回与 Smart Speaker 的向量嵌入最接近的前三个产品,从而有效推荐类似商品,例如 Wireless Earbuds。
总结
MongoDB 的向量搜索能力为构建智能且个性化的应用打开了新的可能。通过将向量索引直接集成到数据库中,MongoDB 简化了整体架构,使数据管理更轻松,相似度搜索更快速。
借助向量搜索,您可以超越简单的关键词匹配,打造能够理解数据上下文与含义的功能。我们鼓励您从 MongoDB Atlas 免费层 开始试验,探索向量索引如何增强您的应用。
向量索引已成为构建现代应用的强大工具。它使您能够对高维数据执行快速高效的相似度搜索,这些高维数据通常被称为向量嵌入。这一能力现已无缝集成至 MongoDB,开发者可以直接在数据库中构建复杂功能。
本文将以实践为导向,手把手带您在 MongoDB 中设置并使用向量索引。从创建第一个索引到运行复杂查询,我们将逐步讲解。您还将学习最佳实践,并通过一个电商商店的产品推荐系统这一真实案例来加深理解。
什么是向量索引?
从本质上讲,向量索引是一种组织向量嵌入以加速相似度搜索的技术。与作用于标量值(如数字或字符串)的传统索引不同,向量索引针对在多维空间中查找“相邻”向量进行了优化。
向量嵌入是对复杂数据(包括文本、图像和音频)的数值化表示。例如,一段产品描述可以被转换为一个向量,类似产品的向量会在空间中彼此更接近。这种距离上的接近性使以下应用成为可能:
在 MongoDB 中设置向量索引
开始之前,您需要一个 MongoDB Atlas 集群。向量搜索是云原生功能。您可以在 MongoDB Atlas 或免费的Community edition中试用该功能。本文将使用 MongoDB Atlas。
步骤 1:创建 MongoDB Atlas 集群
在 MongoDB Atlas 中创建一个新集群。免费 M0 层足以用于测试。
步骤 2:创建集合并插入数据
首先,使用 MongoDB Shell(mongosh)或您偏好的驱动程序连接到集群。然后创建名为products的新集合,并插入包含向量字段的文档。每个文档应表示一个产品,并包含一个embedding字段,用于存放该产品的向量表示。
下面是一个更完整的示例,包含三个不同的产品文档,每个都带有一个随机生成的向量,以演示数据可能的结构。在真实场景中,您会将其替换为由 AI 模型生成的嵌入。
每个文档都包含name、category、description和price,以及关键的embedding字段。该embedding是一个固定大小的数字数组,表示产品描述的语义含义。该数组的大小,即维度,取决于用于生成嵌入的模型。在本示例中,维度为 128。
我们将在这些数据之上构建向量索引,以实现语义搜索和产品推荐。
步骤 3:创建向量索引
当集合中已有带嵌入的数据后,下一步就是创建向量索引。该索引对于实现快速高效的相似度搜索至关重要。下面的命令使用createSearchIndex在embedding字段上构建向量索引。
理解配置
索引配置定义在definition对象的fields数组内。该结构是 MongoDB Atlas 组织向量以实现高速检索的蓝图。
向量索引的核心参数包括:
可选性能参数
对于高级性能调优,MongoDB Atlas 允许您指定可选参数以优化存储与内存:
执行向量搜索查询
索引构建完成后,您可以使用$vectorSearch 聚合阶段来执行相似度查询。
让我们查找与某个查询向量最相似的产品。该查询通常由用户的搜索输入生成。
可选的$project阶段有助于整理输出,并从结果中排除向量数据。
向量索引的最佳实践
在为最佳性能调优向量索引时,您需要在准确性与速度之间取得平衡。关键在于根据您的特定数据集和性能目标来调整索引参数。
选择合适的相似度度量
度量的选择至关重要,因为它定义了两个向量的“相似”程度。您可以参考 MongoDB 文档以进一步了解这些字段。
管理嵌入维度
参数dimensions至关重要,并且必须与您的嵌入模型的输出完全一致。一个常见错误是选择与模型输出不匹配的数字。维度更高的模型能捕捉更多细节,但索引会更大,查询可能变慢。务必查阅模型文档以确认其维度(例如 OpenAI 的text-embedding-ada-002输出 1536 维)。
索引调优
参数numCandidates和numLists对于在速度与准确性之间取得平衡至关重要。一个不错的经验法则是从较低的numCandidates开始,逐步增加,直到达到满意的准确度。对于ivf索引,您也可以尝试不同的numLists,以找到最适合您数据集的平衡点。
示例用例:构建简单推荐系统
让我们将这些概念应用到一个实践示例:电商产品推荐系统。
步骤 1:存储带有嵌入的产品数据
首先,我们将存储产品名称、类别以及各自的向量嵌入。嵌入可以根据产品描述或特性生成。
步骤 2:在embedding上创建向量索引
步骤 3:查询相似产品
现在,让我们查找与 Smart Speaker 相似的产品。我们将使用 Smart Speaker 的嵌入作为查询向量。
此查询将返回与 Smart Speaker 的向量嵌入最接近的前三个产品,从而有效推荐类似商品,例如 Wireless Earbuds。
总结
MongoDB 的向量搜索能力为构建智能且个性化的应用打开了新的可能。通过将向量索引直接集成到数据库中,MongoDB 简化了整体架构,使数据管理更轻松,相似度搜索更快速。
借助向量搜索,您可以超越简单的关键词匹配,打造能够理解数据上下文与含义的功能。我们鼓励您从MongoDB Atlas 免费层开始试验,探索向量索引如何增强您的应用。