一架梯子,一头程序猿,仰望星空!

Java Elasticsearch 查询详解


Elasticsearch的查询功能非常灵活,不了解Elasticsearch查询语法和概念,可以先阅读:ES查询语法

下面介绍Java Elasticsearch查询的写法。

实现ES查询的关键步骤:

  • 创建RestHighLevelClient,Java ES Client对象 - (这个就不再重复,参考Java Elasticsearch Client配置
  • 创建SearchRequest对象 - 负责设置搜索参数
  • 通过Client对象发送请求
  • 处理搜索结果

1. 创建SearchRequest对象

创建SearchRequest对象步骤如下:

  • 创建SearchRequest对象
  • 通过SearchSourceBuilder设置搜索参数
  • 将SearchSourceBuilder绑定到SearchRequest对象

1.1. 初始化SearchRequest对象

创建SearchRequest对象,索引名=posts

SearchRequest searchRequest = new SearchRequest("posts"); 

SearchRequest负责设置搜索参数,包括:ES Query、分页参数等等常用设置。

实际上大部分SearchRequest对象的搜索参数都是通过SearchSourceBuilder对象间接设置。

1.2. 创建SearchSourceBuilder

通过SearchSourceBuilder间接完成搜索参数的设置

// 创建SearchSourceBuilder,构建ES搜索
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); 
// 设置ES查询条件
sourceBuilder.query(QueryBuilders.termQuery("user", "kimchy")); 
// 设置分页参数,偏移从0开始
sourceBuilder.from(0); 
// 设置分页参数,分页大小=5
sourceBuilder.size(5); 
// 设置请求超时时间,60秒
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

// 最后完成SearchRequest请求的参数设置
searchRequest.source(sourceBuilder);

1.3. 构造查询条件

通过上面例子可以知道,Java ES查询条件是通过QueryBuilders工具类构建的,QueryBuilders工具类,支持丰富ES查询条件,详情后面的章节会单独介绍,这里大家只要记得它的作用即可。

// 例子-构建一个Match模糊查询
QueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("user", "kimchy")
                         .fuzziness(Fuzziness.AUTO)
                         .prefixLength(3)
                         .maxExpansions(10);

// 将QueryBuilders构建的查询,绑定到SearchSourceBuilder对象
sourceBuilder.query(matchQueryBuilder);

提示: QueryBuilder是所有Java ES查询的基础接口

1.4. 设置分页参数

通过SearchSourceBuilder设置搜索结果分页参数

// 设置分页参数,偏移从0开始
sourceBuilder.from(0); 
// 设置分页参数,分页大小=5
sourceBuilder.size(5); 

1.5. 设置排序参数

// 根据id字段,升序
builder.sort("id", SortOrder.ASC);

2. 执行请求

SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

3. 处理结果

RestStatus status = searchResponse.status(); // ES请求状态
TimeValue took = searchResponse.getTook(); // 执行时间
Boolean terminatedEarly = searchResponse.isTerminatedEarly();
boolean timedOut = searchResponse.isTimedOut(); // 是否超时
// 获取hits,SearchHits对象包含搜索结果
SearchHits hits = searchResponse.getHits();

TotalHits totalHits = hits.getTotalHits();
// 搜索结果总数
long numHits = totalHits.value;

// 遍历搜索结果
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
     // 获取文档内容,json字符串格式
     String sourceAsString = hit.getSourceAsString();
     // 获取文档内容,Map对象格式
     Map<String, Object> sourceAsMap = hit.getSourceAsMap();
}

4. 完整例子

我们先通过一个简单的ES查询例子,了解Java ES查询的基本写法。

// 首先创建RestClient,后续章节通过RestClient对象进行参数配置。
RestClientBuilder restClientBuilder = RestClient.builder(
                new HttpHost("localhost", 9200, "http"), // 设置ES服务地址,支持多个
                new HttpHost("localhost", 9201, "http"));

// 创建RestHighLevelClient,请求都是通过RestHighLevelClient实例发出去的。
RestHighLevelClient client = new RestHighLevelClient(restClientBuilder);

// 创建SearchRequest对象
SearchRequest searchRequest = new SearchRequest();
// 通过SearchSourceBuilder构建搜索参数
SearchSourceBuilder builder = new SearchSourceBuilder();
// 通过QueryBuilders构建ES查询条件
builder.query(QueryBuilders.termsQuery("order_id", 1,2,3,4,5));
// 设置搜索参数
searchRequest.source(builder);

// 执行ES请求
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 获取搜索到的文档
SearchHits hits = searchResponse.getHits();
// 遍历搜索结果
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
     // 获取文档内容,json字符串格式
     String sourceAsString = hit.getSourceAsString();
     // 获取文档内容,Map对象格式
     Map<String, Object> sourceAsMap = hit.getSourceAsMap();
}