使用 Tablestore Java SDK 的向量检索可按向量相似度返回多元索引中最邻近的数据,并支持最小得分、候选数量和非向量条件过滤。
前提条件
安装Tablestore Java SDK并初始化客户端。SDK 版本需为 5.17.0 或以上。
如需设置
minScore或numCandidates,SDK 版本需为 5.17.5 或以上。
功能说明
向量检索将查询向量与多元索引 Vector 字段中的向量进行近似最近邻(ANN)计算,按创建索引时配置的距离度量算法为结果评分,并返回最邻近的数据。与按字段值匹配的查询不同,向量检索根据向量距离判断数据的相似程度。
调用 search 方法执行向量检索,并将 query 设置为 KnnVectorQuery。
SearchResponse search(SearchRequest request)
以下示例在 embedding 字段中查询与 [1.0, 0.0, 0.0, 0.0] 最邻近的 3 行数据,并按相似度得分从高到低返回结果。
String tableName = "example_table";
String indexName = "example_index";
KnnVectorQuery query = new KnnVectorQuery();
query.setFieldName("embedding");
query.setTopK(3);
query.setFloat32QueryVector(new float[]{1.0f, 0.0f, 0.0f, 0.0f});
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(query);
searchQuery.setLimit(3);
searchQuery.setSort(new Sort(Collections.singletonList(new ScoreSort())));
SearchRequest request = new SearchRequest(tableName, indexName, searchQuery);
SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet();
columnsToGet.setReturnAll(true);
request.setColumnsToGet(columnsToGet);
SearchResponse response = client.search(request);
for (SearchHit hit : response.getSearchHits()) {
System.out.println(hit.getScore() + ": " + hit.getRow());
}
向量字段数量、向量维度和 topK 存在限制。有关限制,请参见多元索引使用限制。
参数说明
查询请求
request 的类型为 SearchRequest,包含以下参数。
|
名称 |
类型 |
说明 |
|
tableName(必选) |
String |
数据表名称。 |
|
indexName(必选) |
String |
多元索引名称。 |
|
searchQuery(必选) |
SearchQuery |
查询条件和通用查询配置。 |
|
columnsToGet(可选) |
SearchRequest.ColumnsToGet |
返回列配置。未设置时只返回主键列。 |
|
timeoutInMillisecond(可选) |
int |
请求级查询超时时间,单位为毫秒。默认值为 |
|
routingValues(可选) |
|
自定义路由字段对应的主键值列表。未配置自定义路由时无需设置。 |
查询配置
request.searchQuery 的类型为 SearchQuery,包含以下参数。
|
名称 |
类型 |
说明 |
|
query(必选) |
Query |
查询条件。向量检索设置为 |
|
offset(可选) |
Integer |
本次查询的起始位置。 |
|
limit(可选) |
Integer |
本次查询返回的最大行数。设置为 |
|
highlight(可选) |
Highlight |
摘要与高亮配置。Vector 字段本身不支持摘要与高亮。 |
|
collapse(可选) |
Collapse |
结果折叠配置,用于按指定列对返回结果去重。 |
|
sort(可选) |
Sort |
返回结果的排序方式。设置为 |
|
trackTotalCount(可选) |
int |
期望统计的最大匹配行数。默认值为 |
|
filter(可选) |
SearchFilter |
对 |
|
aggregationList(可选) |
|
统计聚合配置。 |
|
groupByList(可选) |
|
分组配置。 |
|
token(可选) |
byte[] |
翻页凭证。将上一次响应的 |
向量查询条件
request.searchQuery.query 的类型为 KnnVectorQuery,包含以下参数。
|
名称 |
类型 |
说明 |
|
fieldName(必选) |
String |
向量字段名称。字段类型必须为 Vector,查询向量维度必须与创建多元索引时配置的字段维度相同。 |
|
topK(必选) |
Integer |
要查询的最邻近向量数量,最大值为 |
|
float32QueryVector(必选) |
float[] |
用于计算相似度的 Float32 查询向量。数组长度必须与向量字段维度相同。 |
|
filter(可选) |
Query |
向量检索结果必须同时满足的非向量查询条件。支持组合多个非向量 |
|
weight(可选) |
Float |
向量查询的相关性权重,必须大于或等于 |
|
minScore(可选) |
Float |
最小得分阈值,必须大于或等于 |
|
numCandidates(可选) |
Integer |
每个索引分区计算近邻时访问的候选数量,取值范围为 |
返回列
request.columnsToGet 的类型为 SearchRequest.ColumnsToGet,包含以下参数。
|
名称 |
类型 |
说明 |
|
columns(可选) |
|
要返回的属性列名称。仅 |
|
returnAll(可选) |
boolean |
是否返回数据表中的全部属性列。默认值为 |
|
returnAllFromIndex(可选) |
boolean |
是否返回已建立索引的全部属性列。默认值为 |
返回值
查询响应
search 方法返回 SearchResponse。核心字段如下。
|
名称 |
类型 |
说明 |
|
totalCount |
long |
匹配行数,通过 |
|
rows |
|
本次查询返回的行数据,通过 |
|
searchHits |
|
查询命中结果,通过 |
|
nextToken |
byte[] |
下一页凭证,通过 |
|
isAllSuccess |
boolean |
是否已成功查询全部索引分区,通过 |
查询命中
response.searchHits[] 的类型为 SearchHit,包含以下核心字段。
|
名称 |
类型 |
说明 |
|
row |
Row |
命中的行数据,通过 |
|
score |
Double |
向量查询得分,通过 |
场景示例
按非向量条件和最小得分过滤
设置 filter 要求近邻数据同时满足非向量查询条件,并通过 minScore 排除得分不高于阈值的数据。以下示例只返回 category 等于 book、price 小于 4 且向量得分大于 0.6 的数据。
KnnVectorQuery filteredQuery = new KnnVectorQuery();
filteredQuery.setFieldName("embedding");
filteredQuery.setTopK(10);
filteredQuery.setFloat32QueryVector(
new float[]{1.0f, 0.0f, 0.0f, 0.0f});
filteredQuery.setMinScore(0.6f);
filteredQuery.setFilter(QueryBuilders.bool()
.must(QueryBuilders.term("category", "book"))
.must(QueryBuilders.range("price").lessThan(4)));
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(filteredQuery);
searchQuery.setLimit(10);
调整候选数量
设置 numCandidates 可扩大每个索引分区计算近邻时访问的候选范围。以下示例从 4 个候选中查询最邻近的 3 个向量。
KnnVectorQuery candidateQuery = new KnnVectorQuery();
candidateQuery.setFieldName("embedding");
candidateQuery.setTopK(3);
candidateQuery.setFloat32QueryVector(
new float[]{1.0f, 0.0f, 0.0f, 0.0f});
candidateQuery.setNumCandidates(4);
SearchQuery candidateSearchQuery = new SearchQuery();
candidateSearchQuery.setQuery(candidateQuery);
candidateSearchQuery.setLimit(3);