Elasticsearch API模糊查询简单应用

本文介绍如何利用Elasticsearch的模糊查询功能替代数据库中的LIKE查询,以减轻系统负载并提高查询效率。通过实例演示了如何配置查询条件及解析查询结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Elasticsearch API模糊查询简单应用

es 调用api,一点小心得


在业务逻辑中,查询数据库方向会使用like去查询某些字段,但是like查询不走索引所以会增加负载,在此处优化使用es解决当前问题,首先将数据库表现有数据存入es中

代码块

直接上代码:

/**声明es连接*/
TransportClient client = ESTransportClient.getInstance();
SearchRequestBuilder requestBuilder = client.prepareSearch("fk_caibo").setTypes("yt_user");
// 声明where条件
BoolQueryBuilder qbs = QueryBuilders.boolQuery();

/**此处使用模糊匹配查询 类比数据库中 like*/
QueryBuilder qb1 = QueryBuilders.matchPhraseQuery("NICK_NAME", name);
BoolQueryBuilder bqb1 = QueryBuilders.boolQuery().must(qb1);
qbs.must(bqb1);

requestBuilder.setQuery(qbs);

SearchResponse response = requestBuilder.setFrom(0).setSize(10).execute().actionGet();
SearchHits hits = response.getHits();
if (hits.getHits().length > 0) {
    for (int i = 0; i < hits.getHits().length; i++) {
        SearchHit hit = hits.getHits()[i];
        Map<String, Object> user_map = hit.getSource();
        ...... 
    }
}
<think>首先,用户的问题是关于Elasticsearch Java API客户端的模糊查询和返回查询的示例。用户提到了“模糊查询”和“返回查询”,但我需要澄清“返回查询”可能指的是什么。在Elasticsearch中,常见的查询类型包括模糊查询(fuzzy query),但“返回查询”可能是一个误译或特定术语。回顾上下文,用户引用了几个引用: - 引用[1]:关于QueryBuilders用于生成查询对象。 - 引用[2]:Java中调用Elasticsearch的模糊查询API示例。 - 引用[3]:Elasticsearch Java Api Client中DSL语句的查询方法汇总。 用户特别提到“模糊查询和返回查询”,但引用[3]提到了“地理形状数据查询”,这可能不直接相关。用户说:“我想用户想要获取关于Elasticsearch Java API客户端的查询示例,特别是模糊查询和返回查询的使用方法。” 所以,“返回查询”可能是个错误;或许是“范围查询”(range query)或其他。在Elasticsearch中,常见查询包括模糊查询、范围查询等。用户引用了模糊查询的示例,所以我会专注于模糊查询。假设“返回查询”可能是“范围查询”的笔误,或者用户指的是返回结果的处理。我会基于模糊查询提供示例,并可能包括范围查询作为补充。 关键点:用户要求使用Elasticsearch Java API client。Elasticsearch有多个Java客户端:旧的高层REST客户端(High Level Rest Client, HLRC)和新的官方Java API客户端(Elasticsearch Java API Client),后者是基于新客户端的。用户引用了“Elasticsearch Java Api Client”,所以我会使用新的官方客户端。 在引用中,提到“Elasticsearch Java Api Client”,这可能指的是新客户端。引用[3]说:“Elasticsearch Java Api Client中DSL语句的查询方法汇总”,所以我会使用新客户端的示例。 系统指令要求: - 所有行内数学表达式用$...$格式,但这个问题不涉及数学,所以可能不需要。 - 独立公式用$$...$$格式,但这里没有公式。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,例如[^1]。 - 回答结构清晰,逐步解决问题。 - 保证真实可靠:基于Elasticsearch文档。 用户真正的需求是Elasticsearch Java API客户端的模糊查询示例。可能还包括其他查询类型如范围查询,如果“返回查询”是误译。 结构化回答: 1. **介绍**:简要解释模糊查询。 2. **示例代码**:提供模糊查询的Java代码示例,使用Elasticsearch Java API客户端。 3. **解释**:解释代码。 4. **其他查询**:如果相关,包括范围查询示例。 5. **生成相关问题**:在末尾添加相关问题。 引用处理:用户提供了引用[1]、[2]、[3],但它们是站内引用,我需要自然地引用它们。用户说“上述引用仅供参考”,所以我应该在回答中引用它们,如果适用。 例如: - 引用[2]是关于模糊查询的Java示例。 - 引用[1]关于QueryBuilders,但新客户端不使用QueryBuilders;新客户端使用不同的DSL构建方式。 新Elasticsearch Java API客户端(从7.17+)使用一个流畅的DSL构建器,而不是QueryBuilders。QueryBuilders是旧客户端的。 所以,在回答中,我会使用新客户端的风格。 示例模糊查询: - 模糊查询允许匹配拼写错误或变体。 代码示例: ```java import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.elasticsearch.core.SearchRequest; import co.elastic.clients.elasticsearch.core.SearchResponse; import co.elastic.clients.elasticsearch.core.search.Hit; import co.elastic.clients.json.jackson.JacksonJsonpMapper; import co.elastic.clients.transport.ElasticsearchTransport; import co.elastic.clients.transport.rest_client.RestClientTransport; import org.apache.http.HttpHost; import org.elasticsearch.client.RestClient; import java.io.IOException; public class FuzzyQueryExample { public static void main(String[] args) throws IOException { // 创建客户端 RestClient restClient = RestClient.builder(new HttpHost("localhost", 9200)).build(); ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper()); ElasticsearchClient client = new ElasticsearchClient(transport); // 构建模糊查询 SearchRequest request = SearchRequest.of(s -> s .index("your_index") // 替换为你的索引名 .query(q -> q .fuzzy(f -> f .field("title") // 字段名 .value("Elastisearch") // 查询词,允许模糊匹配 .fuzziness("AUTO") // 模糊度设置 ) ) ); // 执行查询 SearchResponse<Object> response = client.search(request, Object.class); // 处理结果 for (Hit<Object> hit : response.hits().hits()) { System.out.println(hit.source()); } // 关闭客户端 transport.close(); restClient.close(); } } ``` 解释代码: - 使用ElasticsearchClient构建查询。 - 模糊查询通过.fuzzy()方法设置。 - field指定字段,value指定查询词。 - fuzziness设置模糊级别,如"AUTO"。 对于“返回查询”,如果用户指的是范围查询,我可以添加一个示例。 范围查询示例: ```java SearchRequest rangeRequest = SearchRequest.of(s -> s .index("your_index") .query(q -> q .range(r -> r .field("price") // 字段名 .gte(JsonData.of(10)) // 大于等于10 .lte(JsonData.of(100)) // 小于等于100 ) ) ); ``` 在回答中,自然地引用提供的引用。例如,引用[2]提到了模糊查询的参数,我可以在解释时引用。 生成相关问题:在末尾添加3-5个相关问题。 回答结构: 1. 介绍模糊查询。 2. 提供模糊查询示例代码。 3. 解释代码。 4. 如果需要,添加范围查询示例。 5. 总结。 6. 添加相关问题。 使用中文。</think>### Elasticsearch Java API 客户端模糊查询和范围查询示例 根据您的需求,我将使用 Elasticsearch 的官方 Java API 客户端(基于最新版本,如 8.x)提供模糊查询(Fuzzy Query)和范围查询(Range Query)的完整示例。模糊查询用于处理拼写错误或近似匹配(如查询 "Elastisearch" 时匹配 "Elasticsearch"),而范围查询用于基于数值或日期范围过滤结果(如查询价格在 10 到 100 之间的文档)。这些查询基于 Elasticsearch 的 DSL(Domain Specific Language)构建,确保高效性和准确性[^2][^3]。 以下示例使用 Maven 依赖管理。请确保在您的 `pom.xml` 中添加以下依赖(以 Elasticsearch Java API 客户端 8.13.0 为例): ```xml <dependencies> <dependency> <groupId>co.elastic.clients</groupId> <artifactId>elasticsearch-java</artifactId> <version>8.13.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.17.1</version> <!-- 使用兼容版本 --> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-client</artifactId> <version>8.13.0</version> </dependency> </dependencies> ``` ### 1. 模糊查询示例 模糊查询允许匹配近似词项,适用于处理用户输入中的拼写错误。例如,在 "title" 字段中查询 "Elastisearch" 时,可以匹配 "Elasticsearch"。以下是一个完整的 Java 代码示例: ```java import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.elasticsearch.core.SearchRequest; import co.elastic.clients.elasticsearch.core.SearchResponse; import co.elastic.clients.elasticsearch.core.search.Hit; import co.elastic.clients.json.jackson.JacksonJsonpMapper; import co.elastic.clients.transport.ElasticsearchTransport; import co.elastic.clients.transport.rest_client.RestClientTransport; import org.apache.http.HttpHost; import org.elasticsearch.client.RestClient; import java.io.IOException; public class FuzzyQueryExample { public static void main(String[] args) throws IOException { // 1. 创建 Elasticsearch 客户端连接(假设本地运行在 9200 端口) RestClient restClient = RestClient.builder(new HttpHost("localhost", 9200)).build(); ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper()); ElasticsearchClient client = new ElasticsearchClient(transport); // 2. 构建模糊查询请求 SearchRequest request = SearchRequest.of(s -> s .index("products") // 替换为您的索引名,如 "products" .query(q -> q .fuzzy(f -> f .field("title") // 查询字段名,如 "title" .value("Elastisearch") // 查询词,允许模糊匹配(如拼写错误) .fuzziness("AUTO") // 模糊度设置:AUTO 自动计算允许的编辑距离 .maxExpansions(50) // 可选:最大扩展词项数,默认 50 ) ) .size(10) // 返回结果数量 ); // 3. 执行查询并处理结果 SearchResponse<Object> response = client.search(request, Object.class); System.out.println("模糊查询结果数: " + response.hits().total().value()); for (Hit<Object> hit : response.hits().hits()) { System.out.println("文档 ID: " + hit.id() + ", 内容: " + hit.source()); } // 4. 关闭客户端资源 transport.close(); restClient.close(); } } ``` **代码解释:** - **模糊查询参数**: - `field("title")`: 指定查询字段(如引用[2]所述,字段名需与索引映射一致)。 - `value("Elastisearch")`: 查询词,支持模糊匹配(例如,匹配 "Elasticsearch")。 - `fuzziness("AUTO")`: 设置模糊级别(AUTO 根据词长自动调整编辑距离;也可指定数字如 "2" 表示允许最多 2 个字符差异)。 - `maxExpansions(50)`: 可选参数,限制扩展的词项数量,避免性能开销[^2]。 - **执行流程**:客户端连接 Elasticsearch 后,构建查询 DSL,执行并遍历结果。此方法利用了 Elasticsearch 的倒排索引,高效处理近似匹配[^1][^2]。 - **典型应用场景**:搜索建议、用户输入容错处理(如电商商品搜索)。 ### 2. 范围查询示例 如果 "返回查询" 指的是范围查询(Range Query),它用于基于数值、日期或其他可排序字段的范围过滤。例如,查询 "price" 字段在 10 到 100 之间的文档。以下是完整代码示例: ```java import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.elasticsearch.core.SearchRequest; import co.elastic.clients.elasticsearch.core.SearchResponse; import co.elastic.clients.elasticsearch.core.search.Hit; import co.elastic.clients.json.JsonData; import co.elastic.clients.json.jackson.JacksonJsonpMapper; import co.elastic.clients.transport.ElasticsearchTransport; import co.elastic.clients.transport.rest_client.RestClientTransport; import org.apache.http.HttpHost; import org.elasticsearch.client.RestClient; import java.io.IOException; public class RangeQueryExample { public static void main(String[] args) throws IOException { // 1. 创建客户端(同上) RestClient restClient = RestClient.builder(new HttpHost("localhost", 9200)).build(); ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper()); ElasticsearchClient client = new ElasticsearchClient(transport); // 2. 构建范围查询请求 SearchRequest request = SearchRequest.of(s -> s .index("products") // 替换为您的索引名 .query(q -> q .range(r -> r .field("price") // 字段名,如 "price" 或 "date" .gte(JsonData.of(10)) // 大于等于 10 .lte(JsonData.of(100)) // 小于等于 100 // 其他选项:.gt()(大于)、.lt()(小于)、.format("yyyy-MM-dd")(日期格式) ) ) .size(10) ); // 3. 执行查询并处理结果 SearchResponse<Object> response = client.search(request, Object.class); System.out.println("范围查询结果数: " + response.hits().total().value()); for (Hit<Object> hit : response.hits().hits()) { System.out.println("文档 ID: " + hit.id() + ", 内容: " + hit.source()); } // 4. 关闭资源 transport.close(); restClient.close(); } } ``` **代码解释:** - **范围查询参数**: - `field("price")`: 指定范围字段(需为数值、日期等可排序类型)。 - `gte(JsonData.of(10))` 和 `lte(JsonData.of(100))`: 定义范围边界(gte: 大于等于, lte: 小于等于)。日期范围可使用 `.gte(JsonData.of("2023-01-01"))`。 - 支持链式调用,如 `.gt().lt()` 用于开区间[^1][^3]。 - **性能优势**:Elasticsearch 使用 BKD 树索引高效处理范围查询,适合大数据集过滤[^3]。 - **典型应用场景**:价格筛选、时间范围日志查询。 ### 关键注意事项 1. **客户端配置**:确保 Elasticsearch 服务运行(默认 `localhost:9200`)。生产环境中,使用 HTTPS 和认证(如 API 密钥)。 2. **错误处理**:添加 try-catch 块处理 `IOException`(如网络错误)。 3. **性能优化**: - 模糊查询中,设置 `fuzziness` 为 "AUTO" 或小数值以避免过度模糊。 - 范围查询中,对数值字段使用 `keyword` 类型映射可提升效率[^3]。 4. **结果处理**:`hit.source()` 返回文档原始 JSON;您可定义 POJO 类(如 `Product.class`)替代 `Object.class` 进行类型化反序列化。 这些示例基于 Elasticsearch 官方文档和最佳实践,确保真实可靠。模糊查询通过容忍字符差异提升搜索召回率,而范围查询则强化了数据过滤能力[^1][^2][^3]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值