向量检索(KnnVectorQuery)使用数值向量进行近似最近邻查询,可以在大规模数据集中找到最相似的数据项。向量检索功能适用于推荐系统、图像与视频检索、自然语言处理与语义搜索等场景。
场景
向量检索适用于推荐系统、图像与视频检索、自然语言处理与语义搜索等场景。
推荐系统
在电商、社交媒体、视频流媒体等平台中,用户行为、偏好、内容特征等内容可以编码为向量进行存储,然后通过向量检索快速找到与用户兴趣相匹配的产品、文章或视频,实现个性化推荐,提升用户满意度和留存率。
图像与视频检索
在图像识别领域中,将图片转换为向量进行存储,然后通过向量检索快速找到视觉上相似的图片。例如,在电商平台中,用户上传一张图片后,系统能迅速找出具有类似样式、颜色或图案的商品图片。
自然语言处理与语义搜索
在NLP领域,将文本转换为向量表示(例如Word2Vec、BERT嵌入等),然后通过向量检索理解查询语句的语义,并找出语义上最相关的文档、新闻、问答等内容,提升搜索结果的相关性和用户体验。
语音识别与声纹匹配
在语音识别系统中,音频数据经过处理后可以转换为声学特征向量进行存储,然后通过向量检索可以进行声音片段的匹配。例如,在安防系统中进行声纹识别认证,在音频数据库中检索特定的音频片段。
知识图谱与智能问答
知识图谱节点和关系可以表示为向量,通过向量检索能够加速实体链接、关系推理以及智能问答系统的响应速度,使系统能够更准确地理解和回答复杂的问题。
文件去重与内容相似度检测
在版权保护、学术不端检测、新闻聚合去重等领域中,利用文档内容的向量化表示,通过向量检索检测文档之间的相似性。
功能概述
向量检索(KnnVectorQuery)使用数值向量进行近似最近邻查询,可以在大规模数据集中找到最相似的数据项。
使用KnnVectorQuery功能查询数据时,您可以需要指定要查询相似度的向量、要匹配的向量字段以及要查询的最邻近TopK个值,来获取向量字段中与要查询相似度的向量最相似的TopK个值。您还可以组合使用其他非向量检索的查询功能来过滤查询结果。
向量字段说明
使用KnnVectorQuery功能前,您需要在创建多元索引时配置向量字段并指定向量维度、向量数据类型和向量之间的距离度量算法。
向量字段在数据表中对应字段的数据类型必须为字符串类型,在多元索引中的数据类型必须为Float32数组字符串。向量字段的具体配置说明请参见下表。
配置项 | 说明 |
dimension | 向量维度。取值范围请参见多元索引限制。 向量字段的数组长度与该字段的dimension参数配置相等,例如向量字段的值为 |
dataType | 向量的数据类型。当前仅支持Float32,并且Float32不支持NaN和Infinite等极端值。 重要 如果有其他数据类型的向量使用需求,请提交工单联系我们。 |
metricType | 向量之间的距离度量算法。取值范围包括欧氏距离(euclidean)、余弦相似度(cosine)、点积(dot_product)。更多信息,请参见距离度量算法说明。 |
距离度量算法说明
向量检索支持的距离度量算法包括欧氏距离(euclidean)、余弦相似度(cosine)、点积(dot_product)。具体说明请参见下表。评分公式的值越大表示两个向量的相似度越大。
MetricType | 评分公式 | 性能 | 说明 |
欧氏距离 (euclidean) | 较高 | 多维空间中两个向量之间的直线距离。出于性能考虑,表格存储中的欧氏距离算法未进行最后的平方根计算。欧氏距离的评分越大表示两个向量的相似度越大。 | |
点积 (dot_product) | 最高 | 维度相同的两个向量的对应坐标相乘,然后将结果相加。点积的评分越高表示两个向量的相似度越大。 Float32向量必须在写入表前进行归一化(例如使用L2范数进行归一化),否则会出现查询效果差、构建向量索引慢、查询性能差等潜在问题。 | |
余弦相似度 (cosine) | 较低 | 向量空间中两个向量间夹角的余弦值。余弦相似度的评分越高表示两个向量的相似度越大。常用于文本数据的相似度计算。 由于0无法作为除数,无法完成余弦相似度的计算,因此Float32向量的平方和不允许为0 余弦相似度计算复杂,推荐您在写入数据到表之前进行向量的归一化,然后使用点积(dot_product)作为向量距离的度量算法。 |
计费说明
邀测期间,使用向量索引不引入额外的向量索引专用计费项,公测后会进行计费调整。邀测期间当前按照已有模式进行计费。
使用VCU模式(原预留模式)时,使用多元索引查询数据会消耗VCU的计算资源。使用CU模式(原按量模式)时,使用多元索引查询数据会消耗读吞吐量。更多信息,请参见多元索引计量计费。
前提条件
已为多元索引开启向量检索功能。
目前向量检索功能处于邀测中,默认关闭。如果需要使用该功能,请提交工单进行申请或者加入钉钉群36165029092(表格存储技术交流群-3)进行咨询。
创建多元索引时已配置向量字段。具体操作,请参见创建多元索引。
说明如果已创建多元索引,您可以通过动态修改Schema修改多元索引的Schema。具体操作,请参见动态修改schema。
注意事项
使用向量检索时,向量字段类型的个数、维度等存在限制。更多信息,请参见多元索引限制。
接口
向量检索的接口为Search,具体的Query类型为KnnVectorQuery。
参数
参数 | 是否必选 | 说明 |
fieldName | 是 | 向量字段名称。 |
topK | 是 | 查询最邻近的topK个值。关于最大值的说明请参见多元索引限制。 重要 K值越大,召回率越好,但是查询延迟和费用越高。 |
float32QueryVector | 是 | 要查询相似度的向量。 |
filter | 否 | 查询过滤器,支持组合使用任意的非向量检索的查询条件。 |
使用方式
使用向量检索时,您需要先在创建多元索引时配置向量字段,然后使用KnnVectorQuery功能查询数据。此处主要介绍使用KnnVectorQuery功能查询数据的操作。
目前只支持通过SDK方式使用向量检索功能。其中Java SDK从5.17.0版本开始支持,Go SDK请使用最新SDK版本,Python SDK从5.4.4版本开始支持,Node.js SDK从5.5.0版本开始支持。
您可以通过Java SDK、Go SDK、Python SDK或Node.js SDK使用向量检索功能。此处以Java SDK为例介绍使用向量检索的操作。
以下示例用于查询表中与指定向量最邻近的10个向量数据,并且最邻近的向量需要满足Col_Keyword列值等于"hangzhou"且Col_Long列值小于4的条件。
private static void knnVectorQuery(SyncClient client) {
SearchQuery searchQuery = new SearchQuery();
KnnVectorQuery query = new KnnVectorQuery();
query.setFieldName("Col_Vector");
query.setTopK(10); // 返回最邻近的topK。
query.setFloat32QueryVector(new float[]{0.1f, 0.2f, 0.3f, 0.4f});
// 最邻近的向量需要满足Col_Keyword=hangzhou && Col_Long<4条件。
query.setFilter(QueryBuilders.bool()
.must(QueryBuilders.term("Col_Keyword", "hangzhou"))
.must(QueryBuilders.range("Col_Long").lessThan(4))
);
searchQuery.setQuery(query);
searchQuery.setLimit(10);
// 按照分数排序。
searchQuery.setSort(new Sort(Collections.singletonList(new ScoreSort())));
SearchRequest searchRequest = new SearchRequest("<TABLE_NAME>", "<SEARCH_INDEX_NAME>", searchQuery);
SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet();
columnsToGet.setColumns(Arrays.asList("Col_Keyword", "Col_Long"));
searchRequest.setColumnsToGet(columnsToGet);
// 访问Search接口。
SearchResponse resp = client.search(searchRequest);
for (SearchHit hit : resp.getSearchHits()) {
// 打印分数。
System.out.println(hit.getScore());
// 打印数据。
System.out.println(hit.getRow());
}
}
相关文档
多元索引查询类型包括精确查询、多词精确查询、全匹配查询、匹配查询、短语匹配查询、前缀查询、范围查询、通配符查询、模糊查询、多条件组合查询、地理位置查询、嵌套类型查询、向量检索和列存在性查询,您可以选择合适的查询类型进行多维度数据查询。
如果要对结果集进行排序或者翻页,您可以使用排序和翻页功能来实现。具体操作,请参见排序和翻页。
如果要按照某一列对结果集做折叠,使对应类型的数据在结果展示中只出现一次,您可以使用折叠(去重)功能来实现。具体操作,请参见折叠(去重)。
如果要进行数据分析,例如求最值、求和、统计行数等,您可以使用Search接口的统计聚合功能或者SQL查询来实现。具体操作,请参见统计聚合和SQL查询。
如果要快速导出数据,而不关心整个结果集的顺序时,您可以使用ParallelScan接口和ComputeSplits接口实现多并发导出数据。具体操作,请参见并发导出数据。
附录1:与BoolQuery组合使用说明
KnnVectorQuery可以和BoolQuery自由组合使用,不同的组合使用方式会有不同的效果,以下对两种常见的使用方式进行说明。此处以一个Filter命中数据量较少的场景为例进行介绍。
假设表中有1亿张图片,其中用户“a”总计有5万张图片,但是近7天内仅有50张图片,用户“a”希望以图搜图的方式找到7天内最相似的10张图片。由下表说明可知KnnVectorQuery的Filter内部使用BoolQuery的组合使用方式能满足用户“a”的查询需求。
组合使用方式 | 查询条件图示 | 说明 |
KnnVectorQuery的Filter内部使用BoolQuery | KnnVectorQuery命中的行数据为在满足BoolQuery条件下返回最相似的TopK个行数据,SearchRequest返回的结果为TopK行数中的前Size个。 在此示例中,KnnVectorQuery首先通过Filter筛选出该用户“a”在7天内的所有50张图片,然后再从50张图片中找到最相似的10张图片返回给用户。 | |
BoolQuery中使用KnnVectorQuery | BoolQuery的每一个子查询条件会首先进行查询,然后对所有子查询求交集。 在此示例中,KnnVectorQuery会返回表中1亿张图片中最相似的前TopK=500张图片,然后再按照顺序找出用户“a”在7天内的10张图片。但是由于所有图片的TopK=500张图片中不一定包含用户“a”近7天内所有的50张图片,因此该查询方式不一定能找到近7天内的10张图片,甚至找不到任何数据。 |
附录2:向量归一化示例
向量归一化的示例代码如下:
public static float[] l2normalize(float[] v, boolean throwOnZero) {
double squareSum = 0.0f;
int dim = v.length;
for (float x : v) {
squareSum += x * x;
}
if (squareSum == 0) {
if (throwOnZero) {
throw new IllegalArgumentException("can't normalize a zero-length vector");
} else {
return v;
}
}
double length = Math.sqrt(squareSum);
for (int i = 0; i < dim; i++) {
v[i] /= length;
}
return v;
}
- 本页导读