searchByKeywords 用于在指定数据集索引中按关键词检索数据,返回与关键词相关的数据及相关性分数。
bm25:全文检索模式(推荐)。数据集需要配置 FullText。该模式基于全文检索字段(绑定了 FullText 配置的 text 字段)进行分词检索,并使用 BM25 计算相关性分数,适用于强关键词、弱语义、精确词项匹配等场景。semantic_then_match:语义匹配模式。数据集需要配置 Vectorize,并对 text 字段做向量化。该模式基于向量化文本字段(绑定了 Vectorize 配置的 text 字段)进行语义召回,再结合关键词命中情况排序,主要用于兼容历史关键词检索行为。新接入关键词检索时,建议优先使用 bm25 模式。
如果请求中不指定 mode,系统会根据数据集配置自动选择模式:
bm25。semantic_then_match。bm25。public DataApiResponse<SearchResult> searchByKeywords(SearchByKeywordsRequest request) throws ApiClientException, VectorApiException
请求参数为 SearchByKeywordsRequest,SearchByKeywordsRequest 实例包含的参数如下表所示。
| 参数 | 必须 | 类型 | 备注 |
|---|---|---|---|
| resourceId | 二选一 | String | 资源 ID。resourceId 和 collectionName 必须二选一。 |
| collectionName | 二选一 | String | Collection 名称。resourceId 和 collectionName 必须二选一。 |
| indexName | 是 | String | Index 名称。 |
| mode | 否 | String | 检索模式。可选值: 1. bm25:全文检索模式。推荐使用,要求数据集已配置 FullText。2. semantic_then_match:语义匹配模式,要求数据集已配置 Vectorize,并对 text 字段做向量化。不填时,系统会根据数据集配置自动选择。若数据集同时配置 FullText 和 Vectorize,默认使用 bm25。 |
| keywords | 二选一 | List<String> | 关键词列表。keywords 和 query 不能同时传,也不能都不传。建议只传入对检索有实际区分度的词。推荐传入 1-5 个关键词,最多可传 20 个;元素不能为空字符串。推荐: Arrays.asList("机器学习", "检索", "排序")。不推荐: Arrays.asList("帮我", "找一下", "关于", "的")。 |
| query | 二选一 | String | 检索语句,使用 analyzer 分析。keywords 和 query 不能同时传,也不能都不传。建议使用尽可能短的查询内容,并以关键词拼接为主。系统最多使用 20 个有效关键词。推荐长度不超过 100 字节;硬性限制为小于 2048 字节。 |
| caseSensitive | 否 | Boolean | 是否大小写敏感。默认 false。仅对 semantic_then_match 模式生效。 |
| fields | 否 | List<String> | 仅对 bm25 模式生效,用于指定检索哪些全文检索字段。不传时,默认检索数据集中所有 FullText 字段。传入时,每个字段都必须是已配置 FullText 的 text 字段。 |
| fieldsWeights | 否 | Map<String, Float> | 仅对 bm25 模式生效,用于设置各全文检索字段的 BM25 得分权重。Map 的 key 为字段名,必须与 fields 列表一一对应;value 为权重系数。不传时,各字段得分按默认权重 1.0 相加。 |
| bm25K1 | 否 | Double | 仅对 bm25 模式生效。默认值为 1.25,要求大于 0,通常取值在 1.2 到 2.0 之间。k1 越大,高频词越能显著提升分数;k1 越小,词频越容易饱和。一般无需设置。 |
| bm25B | 否 | Double | 仅对 bm25 模式生效。默认值为 0.75,要求在 [0, 1] 之间。b 越大,长文档的分数被压缩得越明显;b 越小,文档长度的影响越有限。一般无需设置。 |
| highlight | 否 | Highlight | 高亮信息配置。传入 highlight 时,highlight.enable 必填。设置为 true 后,返回的 SearchItem 中包含 highlight。开启高亮会增加额外处理开销,仅在需要展示命中位置时开启。 |
| filter | 否 | Map<String, Object> | 过滤条件,详见检索公共参数。默认为空,不做过滤。 |
| outputFields | 否 | List<String> | 要返回的标量字段列表。 1. 不传时,返回所有标量字段。 2. 传入空列表时,不返回标量字段。 3. 字段不存在于 Collection 或参数格式错误时,接口返回错误。 |
| limit | 否 | Integer | 检索结果数量,默认值为 10,上限为 100000。 |
| offset | 否 | Integer | 偏移量。仅分页场景下使用,不建议设置过大值,否则会产生深分页影响。默认值为 0,最小值为 0,语义与 MySQL 的 offset 相同。 |
| advance | 否 | SearchAdvance | 高级参数,普通场景无需设置。详见检索公共参数。 |
| 参数 | 必须 | 类型 | 备注 |
|---|---|---|---|
| enable | 是 | Boolean | 是否返回关键词命中的高亮信息。设置为 true 时,返回结果包含 highlight 字段。 |
返回类型为 DataApiResponse<SearchResult>。
| 参数 | 必须 | 类型 | 备注 |
|---|---|---|---|
| requestId | 是 | String | 请求链路 ID。排查问题时请记录该值。 |
| code | 是 | String | 服务返回码。成功时为 Success。 |
| message | 是 | String | 服务返回信息。 |
| result | 否 | SearchResult | 检索结果。请求失败时可能为空。 |
| 参数 | 必须 | 类型 | 备注 |
|---|---|---|---|
| data | 是 | List<SearchItem> | 查询到的数据列表,SearchItem 结构见下。 |
| totalReturnCount | 是 | Integer | 本次实际返回的结果数量。 |
| tokenUsage | 否 | Object | Token 使用情况。 |
| 参数 | 必须 | 类型 | 备注 |
|---|---|---|---|
| id | 是 | Object | 数据的主键字段值。 |
| fields | 是 | Map<String, Object> | 返回的标量字段。key 为字段名,value 为字段值。 |
| score | 是 | Float | 最终相关性得分。检索结果按 score 排序。 |
| annScore | 否 | Float | 向量检索的原始 ANN 得分。 |
| highlight | 否 | Map<String, Map<String, List<Integer>>> | 高亮信息。第一层 key 为字段名,第二层 key 为命中的关键词或词项,value 为基于字符的 0 起始命中位置列表。 |
运行示例前,请完成以下准备:
- 按“安装与 client 初始化”文档在 Java 项目中引入 VikingDB V2 数据面 SDK。
- AK/SK 在火山引擎控制台“密钥管理”中创建。Host 和 Region 取自地域和访问域名,并按代码读取方式配置
AK、SK环境变量。- Collection 和 Index 名称从 VikingDB 控制台对应资源详情获取。请将代码中的
<YOUR_...>占位符全部替换为真实值。
以下示例适用于已配置 FullText 的数据集。新接入关键词检索时,建议使用该模式。
package org.example.newsubproduct.data.search; import com.volcengine.vikingdb.runtime.core.ClientConfig; import com.volcengine.vikingdb.runtime.core.auth.AuthWithAkSk; import com.volcengine.vikingdb.runtime.enums.Scheme; import com.volcengine.vikingdb.runtime.exception.VectorApiException; import com.volcengine.vikingdb.runtime.vector.model.request.SearchByKeywordsRequest; import com.volcengine.vikingdb.runtime.vector.model.response.DataApiResponse; import com.volcengine.vikingdb.runtime.vector.model.response.SearchResult; import com.volcengine.vikingdb.runtime.vector.service.VectorService; import java.util.Arrays; public class SearchByKeywords { public static void main(String[] args) { VectorService vectorService; try { vectorService = new VectorService( Scheme.HTTPS, "api-vikingdb.vikingdb.cn-beijing.volces.com", "cn-beijing", new AuthWithAkSk(System.getenv("AK"), System.getenv("SK")), ClientConfig.builder().build() ); } catch (Exception e) { System.err.println("Client initialization failed: " + e.getMessage()); e.printStackTrace(); return; } SearchByKeywordsRequest request = SearchByKeywordsRequest.builder() .collectionName("<YOUR_COLLECTION_NAME>") .indexName("<YOUR_INDEX_NAME>") .keywords(Arrays.asList("机器学习", "检索", "排序")) .mode("bm25") .fields(Arrays.asList("f_text")) .outputFields(Arrays.asList("f_text")) .limit(5) .build(); try { DataApiResponse<SearchResult> response = vectorService.searchByKeywords(request); System.out.println("request success:"); System.out.println(response); } catch (VectorApiException vectorApiException) { System.err.println("request vectorApiException:"); System.out.println("apiName: " + vectorApiException.getApiName()); System.out.println("httpStatusCode: " + vectorApiException.getHttpStatusCode()); System.out.println("code: " + vectorApiException.getCode()); System.out.println("message: " + vectorApiException.getMessage()); System.out.println("requestId: " + vectorApiException.getRequestId()); System.out.println( "responseContext: " + vectorApiException.getResponseContext().getBody() ); } catch (Exception e) { System.err.println("request exception, message: " + e.getMessage()); e.printStackTrace(); } } }
以下示例在 bm25 模式下开启高亮信息返回。
package org.example.newsubproduct.data.search; import com.volcengine.vikingdb.runtime.core.ClientConfig; import com.volcengine.vikingdb.runtime.core.auth.AuthWithAkSk; import com.volcengine.vikingdb.runtime.enums.Scheme; import com.volcengine.vikingdb.runtime.exception.VectorApiException; import com.volcengine.vikingdb.runtime.vector.model.request.Highlight; import com.volcengine.vikingdb.runtime.vector.model.request.SearchByKeywordsRequest; import com.volcengine.vikingdb.runtime.vector.model.response.DataApiResponse; import com.volcengine.vikingdb.runtime.vector.model.response.SearchResult; import com.volcengine.vikingdb.runtime.vector.service.VectorService; import java.util.Arrays; public class SearchByKeywordsWithHighlight { public static void main(String[] args) { VectorService vectorService; try { vectorService = new VectorService( Scheme.HTTPS, "api-vikingdb.vikingdb.cn-beijing.volces.com", "cn-beijing", new AuthWithAkSk(System.getenv("AK"), System.getenv("SK")), ClientConfig.builder().build() ); } catch (Exception e) { System.err.println("Client initialization failed: " + e.getMessage()); e.printStackTrace(); return; } Highlight highlight = new Highlight(); highlight.setEnable(true); SearchByKeywordsRequest request = SearchByKeywordsRequest.builder() .collectionName("<YOUR_COLLECTION_NAME>") .indexName("<YOUR_INDEX_NAME>") .keywords(Arrays.asList("机器学习", "检索", "排序")) .mode("bm25") .fields(Arrays.asList("f_text")) .outputFields(Arrays.asList("f_text")) .limit(5) .highlight(highlight) .build(); try { DataApiResponse<SearchResult> response = vectorService.searchByKeywords(request); System.out.println("request success:"); System.out.println(response); } catch (VectorApiException vectorApiException) { System.err.println("request vectorApiException:"); System.out.println("apiName: " + vectorApiException.getApiName()); System.out.println( "httpStatusCode: " + vectorApiException.getHttpStatusCode() ); System.out.println("code: " + vectorApiException.getCode()); System.out.println("message: " + vectorApiException.getMessage()); System.out.println( "requestId: " + vectorApiException.getRequestId() ); System.out.println( "responseContext: " + vectorApiException.getResponseContext().getBody() ); } catch (Exception e) { System.err.println( "request exception, message: " + e.getMessage() ); e.printStackTrace(); } } }