本文指导你完成如何创建矢量数据、为数据编制索引,然后查询容器中的数据的过程。
在使用矢量索引和搜索之前,必须先在 Azure Cosmos DB for NoSQL 中启用矢量搜索。 设置用于矢量搜索的 Azure Cosmos DB 容器后,将创建矢量嵌入策略。 接下来,将向量索引添加到容器索引策略。 然后,创建包含矢量索引和矢量嵌入策略的容器。 最后,对存储的数据执行矢量搜索。
- 一个现有的 Azure Cosmos DB for NoSQL 帐户。
- 如果没有 Azure 订阅, 请尝试免费试用 Azure Cosmos DB for NoSQL。
- 如果有现有的 Azure 订阅, 请创建新的 Azure Cosmos DB for NoSQL 帐户。
- 最新版本的 Azure Cosmos DB Python SDK。
若要为 Azure Cosmos DB for NoSQL 启用矢量搜索,请执行以下步骤:
- 转到 Azure Cosmos DB for NoSQL 资源页。
- 在左窗格中的 “设置”下,选择“ 功能”。
- 在 Azure Cosmos DB for NoSQL 中选择矢量搜索。
- 阅读该功能的说明以确认要启用该功能。
- 选择 “启用” 以在 Azure Cosmos DB for NoSQL 中启用矢量搜索。
提示
或者,使用 Azure CLI 更新帐户的功能,以支持 Azure Cosmos DB for NoSQL 矢量搜索。
az cosmosdb update \
--resource-group <resource-group-name> \
--name <account-name> \
--capabilities EnableNoSQLVectorSearch
注册请求已自动批准,但可能需要 15 分钟才能生效。
以下步骤假定你知道如何 设置 Azure Cosmos DB for NoSQL 帐户并创建数据库。 现有容器当前不支持矢量搜索功能。 需要创建新的容器。 创建容器时,可以指定容器级矢量嵌入策略和矢量索引策略。
让我们以一个示例为例,了解如何为基于 Internet 的书店创建数据库。 你想要存储每本书的标题、作者、ISBN 和说明信息。 还需要定义以下两个属性来包含矢量嵌入:
- 为要执行矢量搜索的字段创建并存储矢量嵌入。
- 在矢量嵌入策略中指定矢量嵌入路径。
- 在容器的索引策略中包含所需的任何向量索引。
对于本文的后续部分,请考虑容器中存储的项的以下结构:
{
"title": "book-title",
"author": "book-author",
"isbn": "book-isbn",
"description": "book-description",
"contentVector": [2, -1, 4, 3, 5, -2, 5, -7, 3, 1],
"coverImageVector": [0.33, -0.52, 0.45, -0.67, 0.89, -0.34, 0.86, -0.78]
}
现在需要定义容器向量策略。 此策略提供了用于通知 Azure Cosmos DB 查询引擎如何处理系统函数中的 VectorDistance
向量属性的信息。 如果选择指定一个,此策略还会向向量索引策略提供必要的信息。
容器向量策略中包括以下信息:
参数 | DESCRIPTION |
---|---|
path |
包含向量的属性路径。 |
datatype |
矢量的元素的类型。 (默认值为 Float32 。) |
dimensions |
路径中每个向量的长度。 (默认值为 1536 。) |
distanceFunction |
用于计算距离/相似度的指标。 (默认值为 Cosine 。) |
对于包含书籍详细信息的示例,矢量策略可能如以下示例所示:
vector_embedding_policy = {
"vectorEmbeddings": [
{
"path": "/coverImageVector",
"dataType": "float32",
"distanceFunction": "dotproduct",
"dimensions": 8
},
{
"path": "/contentVector",
"dataType": "float32",
"distanceFunction": "cosine",
"dimensions": 10
}
]
}
确定矢量嵌入路径后,必须将向量索引添加到索引策略。 索引策略类似于以下示例:
indexing_policy = {
"includedPaths": [
{
"path": "/*"
}
],
"excludedPaths": [
{
"path": "/\"_etag\"/?",
"path": "/coverImageVector/*",
"path": "/contentVector/*"
}
],
"vectorIndexes": [
{"path": "/coverImageVector",
"type": "quantizedFlat"
},
{"path": "/contentVector",
"type": "quantizedFlat"
}
]
}
重要
将向量路径添加到索引策略的 excludedPaths
节,以确保插入性能的优化。 不将向量路径添加到 excludedPaths
会导致矢量插入的请求单元费用和延迟更高。
目前,新容器仅支持 Azure Cosmos DB for NoSQL 中的矢量搜索。 创建容器时,需要同时设置容器向量策略和任何向量索引策略,因为以后无法对其进行修改。
目前,Azure Cosmos DB for NoSQL 的矢量搜索功能仅在新容器上受支持。 创建容器时,应用向量策略。 以后无法修改策略。
try:
container = db.create_container_if_not_exists(
id=CONTAINER_NAME,
partition_key=PartitionKey(path='/id'),
indexing_policy=indexing_policy,
vector_embedding_policy=vector_embedding_policy)
print('Container with id \'{0}\' created'.format(id))
except exceptions.CosmosHttpResponseError:
raise
使用所需的向量策略创建容器并将矢量数据插入容器后,请在查询中使用 VectorDistance 系统函数执行矢量搜索。
假设你想通过查看说明来搜索有关美食食谱的书籍。 首先需要获取查询文本的嵌入。 在这种情况下,你可能希望为查询文本 food recipe
生成嵌入内容。 在为搜索查询生成嵌入后,您可以在矢量搜索查询的VectorDistance
函数中使用该嵌入,以获取与查询类似的所有项。
SELECT TOP 10 c.title, VectorDistance(c.contentVector, [1,2,3,4,5,6,7,8,9,10]) AS SimilarityScore
FROM c
ORDER BY VectorDistance(c.contentVector, [1,2,3,4,5,6,7,8,9,10])
此查询检索书名以及与你的查询相对应的相似度分数。 下面是一个使用 Python 的示例:
query_embedding = [1,2,3,4,5,6,7,8,9,10]
# Query for items
for item in container.query_items(
query='SELECT c.title, VectorDistance(c.contentVector,@embedding) AS SimilarityScore FROM c ORDER BY VectorDistance(c.contentVector,@embedding)',
parameters=[
{"name": "@embedding", "value": query_embedding}
],
enable_cross_partition_query=True):
print(json.dumps(item, indent=True))