目录
一、简介
前面一篇文章已经总结一些索引和文档相关的操作API,本篇文章将介绍Java客户端中如何查询搜索引擎中的数据,同样查询API也是基于RestHighLevelClient实现。
二、查询API详解
es查询API使用大体步骤:
- 构造SearchRequest查询请求对象,支持设置超时时间等信息;创建
SeachRequest
,如果没有传参数,这将针对所有索引运行。如果传了有参数,则按参数所传值为索引,此处“student_info”为索引库名称,大多数搜索参数都添加到SearchSourceBuilder
中,它为搜索请求body中的所有内容提供了setter; - 构造QueryBuilder对象,常见的QueryBuilder有BoolQueryBuilder、MatchQueryBuilder、RangeQueryBuilder等;
- 构造SearchSourceBuilder对象,调用searchSourceBuilder.query(xxxQueryBuilder)方法; //设置查询,可以是任何类型的QueryBuilder。
- 调用searchRequest.source(searchSourceBuilder)方法; //将SearchSourceBuilder添加到SeachRequest。
- 执行查询请求,restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
- 获取响应结果并解析;
RestHighLevelClient查询ES中数据的API主要有:must、match_all、match、should、range、order等等。
search查询的主要参数是SearchRequest,我们的查询条件index、type、字段、字段值 都封装在SearchRequest中;
而index、type是直接封装在SearchRequest的对象中,查询的字段、字段值、查询方式则封装在SearchRequest中的对象属性SearchSourceBuilder中;
下面通过几个常见的查询示例说明如何通过RestHighLevelClient查询es索引中数据。
【a】match_all全部匹配搜索
- QueryBuilders.matchAllQuery()
/**
* match_all全部匹配搜索: QueryBuilders.matchAllQuery()
*/
@Test
void matchAllSearch() throws IOException {
SearchRequest searchRequest = new SearchRequest("student_info");
//构建搜索条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//全部匹配查询
MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
searchSourceBuilder.query(matchAllQueryBuilder);
//设置超时时间
searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
searchRequest.source(searchSourceBuilder);
SearchResponse response = null;
try {
//执行查询请求,获取响应结果
response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
//循环遍历查询结果
System.out.println(JSON.toJSONString(response.getHits()));
for (SearchHit documentFields : response.getHits().getHits()) {
System.out.println(documentFields.getSourceAsMap());
}
restHighLevelClient.close();
}
控制台日志如下:
{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"张三","age":10},"sourceAsString":"{\"age\":10,\"name\":\"张三\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"2","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"李四","age":20},"sourceAsString":"{\"age\":20,\"name\":\"李四\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"3","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"王五","age":30},"sourceAsString":"{\"age\":30,\"name\":\"王五\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"4","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"赵六","age":40},"sourceAsString":"{\"age\":40,\"name\":\"赵六\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"5","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"田七","age":50},"sourceAsString":"{\"age\":50,\"name\":\"田七\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":1.0,"totalHits":{"relation":"EQUAL_TO","value":5}}
{name=张三, age=10}
{name=李四, age=20}
{name=王五, age=30}
{name=赵六, age=40}
{name=田七, age=50}
【b】只返回特定字段
- searchSourceBuilder.fetchSource("name", "age")
通常使用下面两种方法(任意一种)设置查询返回的字段集合,方法还接受一个或多个通配符模式的数组,以控制以更精细的方式包含或排除哪些字段。第一个是获取的字段,第二个是过滤的字段,默认获取全部。
public SearchSourceBuilder fetchSource(@Nullable String include, @Nullable String exclude) {
return this.fetchSource(include == null ? Strings.EMPTY_ARRAY : new String[]{include}, exclude == null ? Strings.EMPTY_ARRAY : new String[]{exclude});
}
public SearchSourceBuilder fetchSource(@Nullable String[] includes, @Nullable String[] excludes) {
FetchSourceContext fetchSourceContext = this.fetchSourceContext != null ? this.fetchSourceContext : FetchSourceContext.FETCH_SOURCE;
this.fetchSourceContext = new FetchSourceContext(fetchSourceContext.fetchSource(), includes, excludes);
return this;
}
/**
* 只返回特定字段: searchSourceBuilder.fetchSource("name", "age")
*/
@Test
void notAllFieldsSearch() throws IOException {
SearchRequest searchRequest = new SearchRequest("student_info");
//构建搜索条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//全部匹配查询
MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
searchSourceBuilder.query(matchAllQueryBuilder);
//设置超时时间
searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//只返回name字段,排除age字段
searchSourceBuilder.fetchSource("name", "age");
searchRequest.source(searchSourceBuilder);
SearchResponse response = null;
try {
//执行查询请求,获取响应结果
response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
//循环遍历查询结果
System.out.println(JSON.toJSONString(response.getHits()));
for (SearchHit documentFields : response.getHits().getHits()) {
System.out.println(documentFields.getSourceAsMap());
}
restHighLevelClient.close();
}
控制台日志如下:
{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"张三"},"sourceAsString":"{\"name\":\"张三\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"2","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"李四"},"sourceAsString":"{\"name\":\"李四\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"3","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"王五"},"sourceAsString":"{\"name\":\"王五\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"4","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"赵六"},"sourceAsString":"{\"name\":\"赵六\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"5","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"田七"},"sourceAsString":"{\"name\":\"田七\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":1.0,"totalHits":{"relation":"EQUAL_TO","value":5}}
{name=张三}
{name=李四}
{name=王五}
{name=赵六}
{name=田七}
【c】match模糊搜索
- QueryBuilders.matchQuery("name", "张")
/**
* match模糊搜索: QueryBuilders.matchQuery("name", "张")
* 查询name字段中包含"张"的记录
*/
@Test
void matchSearch() throws IOException {
SearchRequest searchRequest = new SearchRequest("student_info");
//构建搜索条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//查询name字段中包含"张"的记录
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "张");
searchSourceBuilder.query(matchQueryBuilder);
//设置超时时间
searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
searchRequest.source(searchSourceBuilder);
SearchResponse response = null;
try {
//执行查询请求,获取响应结果
response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
//循环遍历查询结果
System.out.println(JSON.toJSONString(response.getHits()));
for (SearchHit documentFields : response.getHits().getHits()) {
System.out.println(documentFields.getSourceAsMap());
}
restHighLevelClient.close();
}
控制台日志如下:
{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.3862942,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"张三","age":10},"sourceAsString":"{\"age\":10,\"name\":\"张三\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":1.3862942,"totalHits":{"relation":"EQUAL_TO","value":1}}
{name=张三, age=10}
【d】term精确搜索
- QueryBuilders.termQuery("name", "张")
/**
* term精确搜索
*/
@Test
void termSearch() throws IOException {
SearchRequest searchRequest = new SearchRequest("student_info");
//构建搜索条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//精确查询 name精确匹配"张"的记录
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "张");
searchSourceBuilder.query(termQueryBuilder);
//设置超时时间
searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
searchRequest.source(searchSourceBuilder);
SearchResponse response = null;
try {
//执行查询请求,获取响应结果
response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
//循环遍历查询结果
System.out.println(JSON.toJSONString(response.getHits()));
for (SearchHit documentFields : response.getHits().getHits()) {
System.out.println(documentFields.getSourceAsMap());
}
restHighLevelClient.close();
}
控制台日志如下:
{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.3862942,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"张三","age":10},"sourceAsString":"{\"age\":10,\"name\":\"张三\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":1.3862942,"totalHits":{"relation":"EQUAL_TO","value":1}}
{name=张三, age=10}
【e】范围查询
- QueryBuilders.rangeQuery("age")
/**
* 范围查询
*/
@Test
void rangeSearch() throws IOException {
SearchRequest searchRequest = new SearchRequest("student_info");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//构建bool查询
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
//年龄大于等于20,小于等于40的记录
boolQueryBuilder.must(
QueryBuilders.rangeQuery("age") //指定范围查询的字段
.gte("20")
.lte("50")
);
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse response = null;
try {
response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
//循环遍历查询结果
System.out.println(JSON.toJSONString(response.getHits()));
for (SearchHit documentFields : response.getHits().getHits()) {
System.out.println(documentFields.getSourceAsMap());
}
restHighLevelClient.close();
}
控制台日志如下:
{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"2","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"李四","age":20},"sourceAsString":"{\"age\":20,\"name\":\"李四\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"3","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"王五","age":30},"sourceAsString":"{\"age\":30,\"name\":\"王五\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"4","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"赵六","age":40},"sourceAsString":"{\"age\":40,\"name\":\"赵六\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"5","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"田七","age":50},"sourceAsString":"{\"age\":50,\"name\":\"田七\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":1.0,"totalHits":{"relation":"EQUAL_TO","value":4}}
{name=李四, age=20}
{name=王五, age=30}
{name=赵六, age=40}
{name=田七, age=50}
【f】must与查询(相当于and)
- must表示符合条件的,相反的mustnot表示不符合条件的。
/**
* must与查询(相当于and)
*/
@Test
void mustQuery() {
//构造查询请求
SearchRequest searchRequest = new SearchRequest("student_info");
//构造SearchSourceBuilder
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//构造bool查询
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
/**
* must: and且查询
* select * from xxx where name (like '%张%' ) and (age >= 10 and age <= 20)
*/
//1.范围查询: 年龄大于等于10、小于等于20的记录
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age");
rangeQueryBuilder.lte(20).gte(10);
boolQueryBuilder.must(rangeQueryBuilder);
//2.match匹配查询: 姓名中包含"张"的记录
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "张");
boolQueryBuilder.must(matchQueryBuilder);
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse response = null;
try {
//执行请求,返回响应结果
response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(JSON.toJSONString(response.getHits()));
for (SearchHit searchHit : response.getHits().getHits()) {
System.out.println(searchHit.getSourceAsMap());
}
}
控制台日志如下:
{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":2.3862944,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"张三","age":10},"sourceAsString":"{\"age\":10,\"name\":\"张三\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":2.3862944,"totalHits":{"relation":"EQUAL_TO","value":1}}
{name=张三, age=10}
【g】should或查询(相当于or)
/**
* should或查询(相当于or)
*/
@Test
void shouldQuery() {
//构造查询请求
SearchRequest searchRequest = new SearchRequest("student_info");
//构造SearchSourceBuilder
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//构造bool查询
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
/**
* should: or或查询
* select * from xxx where name (like '%张%' ) or (age >= 10 and age <= 20)
*/
//1.范围查询: 年龄大于等于10、小于等于20的记录
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age");
rangeQueryBuilder.lte(20).gte(10);
boolQueryBuilder.should(rangeQueryBuilder);
//2.match匹配查询: 姓名中包含"张"的记录
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "张");
boolQueryBuilder.should(matchQueryBuilder);
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse response = null;
try {
//执行请求,返回响应结果
response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(JSON.toJSONString(response.getHits()));
for (SearchHit searchHit : response.getHits().getHits()) {
System.out.println(searchHit.getSourceAsMap());
}
}
控制台日志如下:
{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":2.3862944,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"张三","age":10},"sourceAsString":"{\"age\":10,\"name\":\"张三\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"2","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"李四","age":20},"sourceAsString":"{\"age\":20,\"name\":\"李四\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":2.3862944,"totalHits":{"relation":"EQUAL_TO","value":2}}
{name=张三, age=10}
{name=李四, age=20}
【h】带排序的搜索
SearchSourceBuilder的排序:
允许添加一个或多个SortBuilder
实例,有四种特殊的实现(Field-,Score-,GeoDistance-和ScriptSortBuilder)。
- sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC)); //按_score降序排序(默认值)
- sourceBuilder.sort(new FieldSortBuilder("_id").order(SortOrder.ASC)); //按_id字段进行升序排序
- searchSourceBuilder.sort("age", SortOrder.DESC);
/**
* 带排序的搜索: searchSourceBuilder.sort("age", SortOrder.DESC);
*/
@Test
void sortQuery() throws IOException {
SearchRequest searchRequest = new SearchRequest("student_info");
//构建搜索条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
searchSourceBuilder.query(matchAllQueryBuilder);
//设置超时时间
searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//按age降序排序
searchSourceBuilder.sort("age", SortOrder.DESC);
searchRequest.source(searchSourceBuilder);
SearchResponse response = null;
try {
//执行查询请求,获取响应结果
response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
//循环遍历查询结果
System.out.println(JSON.toJSONString(response.getHits()));
for (SearchHit documentFields : response.getHits().getHits()) {
System.out.println(documentFields.getSourceAsMap());
}
restHighLevelClient.close();
}
控制台日志如下:
{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"5","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":null,"seqNo":-2,"sortValues":[50],"sourceAsMap":{"name":"田七","age":50},"sourceAsString":"{\"age\":50,\"name\":\"田七\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"4","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":null,"seqNo":-2,"sortValues":[40],"sourceAsMap":{"name":"赵六","age":40},"sourceAsString":"{\"age\":40,\"name\":\"赵六\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"3","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":null,"seqNo":-2,"sortValues":[30],"sourceAsMap":{"name":"王五","age":30},"sourceAsString":"{\"age\":30,\"name\":\"王五\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"2","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":null,"seqNo":-2,"sortValues":[20],"sourceAsMap":{"name":"李四","age":20},"sourceAsString":"{\"age\":20,\"name\":\"李四\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":null,"seqNo":-2,"sortValues":[10],"sourceAsMap":{"name":"张三","age":10},"sourceAsString":"{\"age\":10,\"name\":\"张三\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":null,"totalHits":{"relation":"EQUAL_TO","value":5}}
{name=田七, age=50}
{name=赵六, age=40}
{name=王五, age=30}
{name=李四, age=20}
{name=张三, age=10}
【i】分页搜索
- searchSourceBuilder.from(1); //设置确定结果要从哪个索引开始搜索的from选项,默认为0
- searchSourceBuilder.size(2); //设置确定搜素命中返回数的size选项,默认为10
/**
* 分页搜索: searchSourceBuilder.from(1); searchSourceBuilder.size(2);
*/
@Test
void paginationQuery() throws IOException {
SearchRequest searchRequest = new SearchRequest("student_info");
//构建搜索条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
searchSourceBuilder.query(matchAllQueryBuilder);
//设置超时时间
searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//按age降序排序
searchSourceBuilder.sort("age", SortOrder.DESC);
//从第一条记录开始,每页展示两条
searchSourceBuilder.from(1);
searchSourceBuilder.size(2);
searchRequest.source(searchSourceBuilder);
SearchResponse response = null;
try {
//执行查询请求,获取响应结果
response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
//循环遍历查询结果
System.out.println(JSON.toJSONString(response.getHits()));
for (SearchHit documentFields : response.getHits().getHits()) {
System.out.println(documentFields.getSourceAsMap());
}
restHighLevelClient.close();
}
控制台日志如下:
{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"4","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":null,"seqNo":-2,"sortValues":[40],"sourceAsMap":{"name":"赵六","age":40},"sourceAsString":"{\"age\":40,\"name\":\"赵六\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"3","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":null,"seqNo":-2,"sortValues":[30],"sourceAsMap":{"name":"王五","age":30},"sourceAsString":"{\"age\":30,\"name\":\"王五\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":null,"totalHits":{"relation":"EQUAL_TO","value":5}}
{name=赵六, age=40}
{name=王五, age=30}
【j】高亮搜索
通过在SearchSourceBuilder上设置HighlightBuilder,可以实现高亮搜索结果。
- HighlightBuilder highlightBuilder = new HighlightBuilder();
- highlightBuilder.field("name");
- highlightBuilder.preTags("<span style=\"color:red\">");
- highlightBuilder.postTags("</span>");
- searchSourceBuilder.highlighter(highlightBuilder);
/**
* 高亮显示搜索
*/
@Test
void highLightQuery() throws IOException {
SearchRequest searchRequest = new SearchRequest("student_info");
//构建搜索条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "张");
//设置超时时间
searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//按age降序排序
searchSourceBuilder.sort("age", SortOrder.DESC);
HighlightBuilder highlightBuilder = new HighlightBuilder();
//指定高亮字段
highlightBuilder.field("name");
//指定前置标签
highlightBuilder.preTags("<span style=\"color:red\">");
//指定后置标签
highlightBuilder.postTags("</span>");
searchSourceBuilder.highlighter(highlightBuilder);
searchSourceBuilder.query(matchQueryBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse response = null;
try {
//执行查询请求,获取响应结果
response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
//循环遍历查询结果
System.out.println(JSON.toJSONString(response.getHits()));
for (SearchHit searchHit : response.getHits().getHits()) {
Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
//获取对应的高亮域
Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
//获取高亮字段
HighlightField name = highlightFields.get("name");
if (null != name) {
// 为name串值增加自定义的高亮标签
Text[] nameTexts = name.fragments();
StringBuilder newName = new StringBuilder();
for (Text text : nameTexts) {
newName.append(text);
}
//将追加了高亮标签的串值重新填充到对应的对象
sourceAsMap.put("name", newName.toString());
}
System.out.println(sourceAsMap);
}
restHighLevelClient.close();
}
控制台日志输出:
{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{"name":{"fragment":true,"fragments":[{"fragment":true}],"name":"name"}},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":null,"seqNo":-2,"sortValues":[10],"sourceAsMap":{"name":"张三","age":10},"sourceAsString":"{\"age\":10,\"name\":\"张三\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":null,"totalHits":{"relation":"EQUAL_TO","value":1}}
{name=<span style="color:red">张</span>三, age=10}
【k】一次查询多个条件
- MultiSearchRequest multiSearchRequest = new MultiSearchRequest();
- restHighLevelClient.msearch(multiSearchRequest, RequestOptions.DEFAULT)
/**
* 一次查询多个条件: restHighLevelClient.msearch(multiSearchRequest, RequestOptions.DEFAULT)
*/
@Test
void multiSearchQuery() throws IOException {
//构造请求MultiSearchRequest
MultiSearchRequest multiSearchRequest = new MultiSearchRequest();
/*
* 第一个SearchRequest
*/
SearchRequest firstSearchRequest = new SearchRequest("student_info");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "张");
searchSourceBuilder.query(matchQueryBuilder);
firstSearchRequest.source(searchSourceBuilder);
multiSearchRequest.add(firstSearchRequest);
/*
* 第二个SearchRequest
*/
SearchRequest secondSearchRequest = new SearchRequest("student_info");
searchSourceBuilder = new SearchSourceBuilder();
matchQueryBuilder = QueryBuilders.matchQuery("name", "李");
searchSourceBuilder.query(matchQueryBuilder);
secondSearchRequest.source(searchSourceBuilder);
multiSearchRequest.add(secondSearchRequest);
MultiSearchResponse multiSearchResponse;
try {
//执行请求,返回多个响应
multiSearchResponse = restHighLevelClient.msearch(multiSearchRequest, RequestOptions.DEFAULT);
multiSearchResponse.forEach(t -> {
SearchResponse response = t.getResponse();
//循环遍历查询结果
System.out.println(JSON.toJSONString(response.getHits()));
for (SearchHit searchHit : response.getHits().getHits()) {
System.out.println(searchHit.getSourceAsMap());
}
});
} catch (IOException e) {
e.printStackTrace();
}
restHighLevelClient.close();
}
控制台日志输出:
{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.3862942,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"张三","age":10},"sourceAsString":"{\"age\":10,\"name\":\"张三\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":1.3862942,"totalHits":{"relation":"EQUAL_TO","value":1}}
{name=张三, age=10}
{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"2","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.3862942,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"李四","age":20},"sourceAsString":"{\"age\":20,\"name\":\"李四\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":1.3862942,"totalHits":{"relation":"EQUAL_TO","value":1}}
{name=李四, age=20}
三、总结
以上总结了一些常见的ES Java客户端查询API相关的示例,在实际项目中,得根据具体的业务需求,灵活构造不同的xxxQueryBuilder实现。希望以上代码可以帮助到读者,也能为以后再次使用时提供帮助。由于笔者水平有限,以上如有不对之处,还望指正,相互学习,一起进步!