文档

向量检索

向量检索(KnnVectorQuery)使用数值向量进行近似最近邻查询,可以在大规模数据集中找到最相似的数据项。向量检索功能适用于推荐系统、图像与视频检索、自然语言处理与语义搜索等场景。

场景

向量检索适用于推荐系统、图像与视频检索、自然语言处理与语义搜索等场景。

  • 推荐系统

    在电商、社交媒体、视频流媒体等平台中,用户行为、偏好、内容特征等内容可以编码为向量进行存储,然后通过向量检索快速找到与用户兴趣相匹配的产品、文章或视频,实现个性化推荐,提升用户满意度和留存率。

  • 图像与视频检索

    在图像识别领域中,将图片转换为向量进行存储,然后通过向量检索快速找到视觉上相似的图片。例如,在电商平台中,用户上传一张图片后,系统能迅速找出具有类似样式、颜色或图案的商品图片。

  • 自然语言处理与语义搜索

    在NLP领域,将文本转换为向量表示(例如Word2Vec、BERT嵌入等),然后通过向量检索理解查询语句的语义,并找出语义上最相关的文档、新闻、问答等内容,提升搜索结果的相关性和用户体验。

  • 语音识别与声纹匹配

    在语音识别系统中,音频数据经过处理后可以转换为声学特征向量进行存储,然后通过向量检索可以进行声音片段的匹配。例如,在安防系统中进行声纹识别认证,在音频数据库中检索特定的音频片段。

  • 知识图谱与智能问答

    知识图谱节点和关系可以表示为向量,通过向量检索能够加速实体链接、关系推理以及智能问答系统的响应速度,使系统能够更准确地理解和回答复杂的问题。

  • 文件去重与内容相似度检测

    在版权保护、学术不端检测、新闻聚合去重等领域中,利用文档内容的向量化表示,通过向量检索检测文档之间的相似性。

功能概述

向量检索(KnnVectorQuery)使用数值向量进行近似最近邻查询,可以在大规模数据集中找到最相似的数据项。

使用KnnVectorQuery功能查询数据时,您可以需要指定要查询相似度的向量、要匹配的向量字段以及要查询的最邻近TopK个值,来获取向量字段中与要查询相似度的向量最相似的TopK个值。您还可以组合使用其他非向量检索的查询功能来过滤查询结果。

向量字段说明

使用KnnVectorQuery功能前,您需要在创建多元索引时配置向量字段并指定向量维度、向量数据类型和向量之间的距离度量算法。

向量字段在数据表中对应字段的数据类型必须为字符串类型,在多元索引中的数据类型必须为Float32数组字符串。向量字段的具体配置说明请参见下表。

配置项

说明

dimension

向量维度。取值范围请参见多元索引限制

向量字段的数组长度与该字段的dimension参数配置相等,例如向量字段的值为[1, 5.1, 4.7, 0.08]字符串,该字段的维度为4。

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 SDKGo SDKPython SDKNode.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());
    }
}

相关文档

附录1:与BoolQuery组合使用说明

KnnVectorQuery可以和BoolQuery自由组合使用,不同的组合使用方式会有不同的效果,以下对两种常见的使用方式进行说明。此处以一个Filter命中数据量较少的场景为例进行介绍。

假设表中有1亿张图片,其中用户“a”总计有5万张图片,但是近7天内仅有50张图片,用户“a”希望以图搜图的方式找到7天内最相似的10张图片。由下表说明可知KnnVectorQuery的Filter内部使用BoolQuery的组合使用方式能满足用户“a”的查询需求。

组合使用方式

查询条件图示

说明

KnnVectorQuery的Filter内部使用BoolQuery

image

KnnVectorQuery命中的行数据为在满足BoolQuery条件下返回最相似的TopK个行数据,SearchRequest返回的结果为TopK行数中的前Size个。

在此示例中,KnnVectorQuery首先通过Filter筛选出该用户“a”在7天内的所有50张图片,然后再从50张图片中找到最相似的10张图片返回给用户。

BoolQuery中使用KnnVectorQuery

image

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;
  }

  • 本页导读