--- title: "Easysearch Java SDK 2.0.x 使用指南(三)" date: 2024-12-21 lastmod: 2024-12-21 description: "本文介绍 Easysearch Java SDK 2.0.2 的三种核心查询:QueryString(灵活全文检索)、Bool Query(复杂多条件查询)和 Constant Score(高效过滤与统一评分),并提供代码示例及使用场景分析。" tags: ["Easysearch", "client", "SDK"] summary: "在 Easysearch Java SDK 2.0.x 使用指南(一) 中,我们介绍了 Easysearch Java SDK 2.0.2 的基本使用和批量操作功能。 在 Easysearch Java SDK 2.0.x 使用指南(二) 中,则详细介绍了索引管理相关的功能,包括索引的创建、删除、开关、刷新、滚动等操作,以及新版 SDK 提供的同步和异步两种调用方式。 本篇文章将继续向大家介绍 Easysearch Java SDK 2.0.2 的 Query 的使用。 1. QueryString:灵活的全文检索 # QueryString 查询允许开发者以类似 Easysearch Query DSL 的语法执行全文检索,非常适合处理用户输入的复杂搜索条件。 基本概念 # fields:指定要检索的字段列表。 query:查询字符串,支持布尔操作符(如 AND、OR、NOT)。 default_operator:当查询字符串中未明确操作符时使用的默认逻辑操作符。 analyze_wildcard:是否对通配符查询进行分析。 代码示例 # 以下示例展示了如何通过新版 Java 客户端构建一个 QueryString 查询,用于检索标题和内容中同时包含 easysearch 和 java 的文档: @Test public void testQueryString() { // 定义 JSON 查询字符串 String jsonQuery = "{\n" + " \"query_string\": {\n" + " \"fields\": [\"title\", \"content\"],\n" + " \"query\": \"easysearch AND java\",\n" + " \"default_operator\": \"AND\",\n" + " \"analyze_wildcard\": true\n" + " }\n" + "}"; // 使用 JacksonJsonpMapper 解析 JSON 字符串 JacksonJsonpMapper mapper = new JacksonJsonpMapper(); JsonParser parser = mapper." --- 在 [Easysearch Java SDK 2.0.x 使用指南(一)](./easysearch-java-client-1.md) 中,我们介绍了 Easysearch Java SDK 2.0.2 的基本使用和批量操作功能。 在 [Easysearch Java SDK 2.0.x 使用指南(二)](./easysearch-java-client-2.md) 中,则详细介绍了索引管理相关的功能,包括索引的创建、删除、开关、刷新、滚动等操作,以及新版 SDK 提供的同步和异步两种调用方式。 本篇文章将继续向大家介绍 Easysearch Java SDK 2.0.2 的 Query 的使用。 --- ## 1. QueryString:灵活的全文检索 **QueryString 查询**允许开发者以类似 Easysearch Query DSL 的语法执行全文检索,非常适合处理用户输入的复杂搜索条件。 ### 基本概念 - **`fields`**:指定要检索的字段列表。 - **`query`**:查询字符串,支持布尔操作符(如 AND、OR、NOT)。 - **`default_operator`**:当查询字符串中未明确操作符时使用的默认逻辑操作符。 - **`analyze_wildcard`**:是否对通配符查询进行分析。 ### 代码示例 以下示例展示了如何通过新版 Java 客户端构建一个 `QueryString` 查询,用于检索标题和内容中同时包含 `easysearch` 和 `java` 的文档: ```java @Test public void testQueryString() { // 定义 JSON 查询字符串 String jsonQuery = "{\n" + " \"query_string\": {\n" + " \"fields\": [\"title\", \"content\"],\n" + " \"query\": \"easysearch AND java\",\n" + " \"default_operator\": \"AND\",\n" + " \"analyze_wildcard\": true\n" + " }\n" + "}"; // 使用 JacksonJsonpMapper 解析 JSON 字符串 JacksonJsonpMapper mapper = new JacksonJsonpMapper(); JsonParser parser = mapper.jsonProvider().createParser(new StringReader(jsonQuery)); Query query = Query._DESERIALIZER.deserialize(parser, mapper); // 提取 QueryStringQuery 并构建最终查询 QueryStringQuery queryStringQuery = query.queryString(); Query finalQuery = Query.of(q -> q.queryString(queryStringQuery)); // 输出最终查询对象 System.out.println(finalQuery); } ``` ### 代码解析 1. **构建 JSON 查询字符串**:定义了 `query_string` 查询的核心参数,包括字段列表和查询条件。 2. **解析 JSON**:使用 `JacksonJsonpMapper` 将 JSON 字符串解析为 Java 对象。 3. **提取 QueryStringQuery**:从解析后的 `Query` 对象中获取 `QueryStringQuery`。 4. **封装最终查询**:通过 `Query.of` 方法将 `QueryStringQuery` 封装为最终的 `Query` 对象。 ### 使用场景 - 用户输入的搜索条件需要支持布尔逻辑。 - 需要在多个字段中进行全文检索。 - 支持模糊搜索(如通配符)的场景。 --- ## 2. Bool Query:构建复杂的多条件查询 Bool Query 可以将多个查询子句组合成一个高级查询。这些子句通过布尔逻辑组合在一起,用于查找结果中返回的匹配文档。 ### Bool Query 的核心子句 | 子句 | 行为 | | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `must` | 逻辑"与"运算符。结果必须匹配此子句中的所有查询。 | | `must_not` | 逻辑"非"运算符。所有匹配此子句中查询的文档都会从结果中排除。 | | `should` | 逻辑"或"运算符。结果必须匹配至少一个查询。匹配的 `should` 子句越多,文档的相关性得分越高。你可以使用 `minimum_should_match` 参数设置必须匹配的最小查询数量。如果查询包含 `must` 或 `filter` 子句,则 `minimum_should_match` 的默认值为 0。否则,`minimum_should_match` 的默认值为 1。 | | `filter` | 逻辑"与"运算符,在应用其他查询之前首先应用,以减少数据集。`filter` 子句中的查询是一个是或否选项。如果文档匹配查询,则会将其返回到结果中;否则不会返回。`filter` 查询的结果通常会被缓存,以实现更快的返回。使用 `filter` 查询可根据精确匹配、范围、日期或数字来过滤结果。 | ### 基于 JSON 的代码示例 以下代码展示了如何通过 JSON 字符串构建一个复杂的 `BoolQuery`: ```java @Test public void testBoolQueryString() { // 定义 JSON 查询字符串 String jsonQuery = "{\n" + " \"bool\": {\n" + " \"must\": [\n" + " { \"match\": { \"title\": \"easysearch\" } },\n" + " { \"match\": { \"content\": \"java programming\" } }\n" + " ],\n" + " \"should\": [\n" + " { \"term\": { \"category\": \"technology\" } },\n" + " { \"term\": { \"category\": \"programming\" } }\n" + " ],\n" + " \"must_not\": [\n" + " { \"term\": { \"status\": \"draft\" } },\n" + " { \"range\": { \"publish_date\": { \"lt\": \"2020-01-01\" } } }\n" + " ],\n" + " \"filter\": [\n" + " { \"range\": { \"rating\": { \"gte\": 4 } } },\n" + " { \"terms\": { \"tags\": [\"search\", \"database\"] } }\n" + " ],\n" + " \"minimum_should_match\": 1\n" + " }\n" + "}"; // 解析 JSON 并构建查询 JacksonJsonpMapper mapper = new JacksonJsonpMapper(); JsonParser parser = mapper.jsonProvider().createParser(new StringReader(jsonQuery)); Query query = Query._DESERIALIZER.deserialize(parser, mapper); // 提取 BoolQuery 并构建最终查询 BoolQuery boolQuery = query.bool(); Query finalQuery = Query.of(q -> q.bool(boolQuery)); // 输出最终查询对象 System.out.println(finalQuery); } ``` ### 使用 Builder 模式构建 BoolQuery 新版 Java 客户端还提供了类型安全的 `Builder` 模式,简化了复杂查询的构建过程: ```java @Test public void testBooleanQuery() throws IOException { // 构建 BoolQuery BoolQuery.Builder boolQueryBuilder = new BoolQuery.Builder(); // 添加 must 子句 boolQueryBuilder.must(new MatchQuery.Builder().field("title").query("easysearch").build()._toQuery()); boolQueryBuilder.must(new MatchQuery.Builder().field("content").query("java programming").build()._toQuery()); // 添加 should 子句 boolQueryBuilder.should(new TermQuery.Builder().field("category").value("technology").build()._toQuery()); boolQueryBuilder.should(new TermQuery.Builder().field("category").value("programming").build()._toQuery()); // 添加 must_not 子句 boolQueryBuilder.mustNot(new TermQuery.Builder().field("status").value("draft").build()._toQuery()); // 添加 filter 子句 boolQueryBuilder.filter(new RangeQuery.Builder().field("rating").gte("4").build()._toQuery()); // 构建查询 Query query = new Query(boolQueryBuilder.build()); System.out.println(query); } ``` ### 使用场景 - 构建复杂的多条件查询。 - 满足高级搜索需求,例如结合全文检索和精确匹配。 - 实现复杂的逻辑,如过滤无关数据、优先特定条件。 --- ## 3. Constant score query:统一评分的过滤查询 Constant score 查询用于包装一个 filter 查询,并为所有匹配的文档分配一个统一的相关性分数。这种查询方式不考虑词频 (TF) 和逆文档频率 (IDF),适合那些只关心文档是否匹配而不关心相关度排序的场景。 ### 基本概念 **`constant_score` 的参数** - **`filter`** - (必需) 您希望运行的过滤查询。任何返回的文档都必须匹配此查询。 - 过滤查询不计算相关性得分。为了提高性能,Easysearch 会自动缓存常用的过滤查询。 - **`boost`** - (可选) 用作每个匹配过滤查询的文档的常量相关性得分的浮点数。默认为 1.0。 ### 基于 JSON 的代码示例 ```java @Test public void testConstantScoreQuery() { // 定义 JSON 查询字符串 String jsonQuery = "{\n" + " \"constant_score\": {\n" + " \"filter\": {\n" + " \"term\": { \"status\": \"published\" }\n" + " },\n" + " \"boost\": 1.2\n" + " }\n" + "}"; // 解析 JSON 并构建查询 JacksonJsonpMapper mapper = new JacksonJsonpMapper(); JsonParser parser = mapper.jsonProvider().createParser(new StringReader(jsonQuery)); Query query = Query._DESERIALIZER.deserialize(parser, mapper); // 提取 ConstantScoreQuery 并构建最终查询 ConstantScoreQuery constantScoreQuery = query.constantScore(); Query finalQuery = Query.of(q -> q.constantScore(constantScoreQuery)); System.out.println(finalQuery); } ``` ### 使用 Builder 模式构建 ConstantScoreQuery ```java @Test public void testConstantScoreQueryBuilder() { // 使用 Builder 构建 ConstantScoreQuery ConstantScoreQuery.Builder constantScoreBuilder = new ConstantScoreQuery.Builder(); // 创建 filter 查询 TermQuery termQuery = new TermQuery.Builder() .field("status") .value("published") .build(); // 设置 filter 和 boost constantScoreBuilder .filter(termQuery._toQuery()) .boost(1.2f); // 构建最终查询 Query query = Query.of(q -> q.constantScore(constantScoreBuilder.build())); System.out.println(query); } ``` ### 使用场景 1. **精确匹配过滤** - 查找特定状态的文档 - 不需要考虑相关度排序 2. **性能优化** - 过滤查询会被缓存 - 不计算相关性分数,查询更快 3. **自定义评分** - 需要给所有匹配文档统一分数 - 覆盖默认的相关性评分 4. **布尔查询的组件** - 作为 bool 查询的一部分 - 用于预过滤或调整特定文档集的分数 通过使用 Constant score 查询,我们可以在需要简单过滤和统一评分的场景中获得更好的性能和更简单的实现。这种查询方式特别适合那些不需要复杂相关性计算的应用场景。 --- ## 总结 本文介绍了 Easysearch Java SDK 2.0.2 中的三种核心查询:Query String、Bool Query 和 Constant Score。 Query String 擅长灵活处理用户输入的全文检索,支持布尔逻辑和通配符。Bool Query 则通过组合 must、must_not、should 和 filter 等子句,满足复杂的多条件查询需求。Constant Score 则专注于高效过滤和统一评分,适用于不需要排序的场景。 --- **想要了解更多?** - **客户端 Maven 地址:** [https://mvnrepository.com/artifact/com.infinilabs/easysearch-client/2.0.2](https://mvnrepository.com/artifact/com.infinilabs/easysearch-client/2.0.2) - **更详细的文档和示例代码在 [官网](https://docs.infinilabs.com/easysearch/main/docs/references/client/client-api/) 持续更新中,请随时关注!** 大家有啥问题或者建议,也欢迎随时反馈!