ES之Java High Level REST Client使用

本文用到的_*只是用来代指某一个值,没有特殊含义。

查询

一般的查询

查询里面必须的两个东西是SearchRequestSearchSourceBuilder,且必须将SearchSourceBuilder加入到SearchRequest

  1. 最简单的查询所有:
1
2
3
4
5
SearchRequest searchRequest = new SearchRequest();    //定义查询请求,可带索引参数
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); //定义请求体
searchSourceBuilder.query(QueryBuilders.matchAllQuery()); //请求体内容为 match_all
searchRequest.source(searchSourceBuilder); //将请求体放入查询请求中
searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); //设置超时时间,60s

可指定序列和类别

1
2
3
4
5
SearchRequest searchRequest = new SearchRequest("_index");   //设置索引
searchRequest.types("_type"); //设置类别
searchRequest.routing("_routing"); //设置路由
searchRequest.indicesOptions(IndicesOptions.lenientExpandOpen()); //如何解析以及如何扩展通配符表达式
searchRequest.preference("_local"); //优先执行本地搜索,默认是整个分片上随机
  1. 指定排序规则和分页返回
1
2
3
4
5
6
searchSourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC));       //默认按评分_score降序
//sourceBuilder.sort(new FieldSortBuilder("_uid").order(SortOrder.ASC)); //自定义按_uid升序

searchSourceBuilder.sort(new FieldSortBuilder("time").order(SortOrder.fromString("desc"))); //指定按照时间降序排序
searchSourceBuilder.from(0); //起始位置,默认为0,主要用于分页
searchSourceBuilder.size(5); //限制大小,默认为10
  1. 源过滤

    1
    2
    3
    4
    5
    6
    7
    8
    searchSourceBuilder.fetchSource(false);               //默认关闭对_source的检索
    //用通配符方式的数组来控制哪些字段包含或排除
    //String[] includeFields = new String[] {"title", "user", "innerObject.*"};
    //String[] excludeFields = new String[] {"_type"};
    //searchSourceBuilder.fetchSource(includeFields, excludeFields);

    searchSourceBuilder.fetchSource(new FetchSourceContext(new String[]{"name", "description"})); //指定返回的字段,只包含name和description
    searchSourceBuilder.fetchSource(null,new FetchSourceContext(new String[]{"name", "description"})); //指定返回的字段,排除name和description
  2. term查询

1
2
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); 
searchSourceBuilder.query(QueryBuilders.termQuery("_name", "_value"));
  1. match查询
1
2
3
4
5
6
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); 
MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("_name", "_value");
matchQueryBuilder.fuzziness(Fuzziness.AUTO); //启用模糊匹配
matchQueryBuilder.prefixLength(3); //设置前缀长度
matchQueryBuilder.maxExpansions(10); //设置最大扩展选项
searchSourceBuilder.query(matchQueryBuilder);

也可以下面方式创建:

1
2
3
4
5
6
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
QueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("_name""_value")
.fuzziness(Fuzziness.AUTO)
.prefixLength(3)
.maxExpansions(10);
searchSourceBuilder.query(matchQueryBuilder);

  1. 突出显示
1
2
3
4
5
6
7
8
9
10
11
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
HighlightBuilder highlightBuilder = new HighlightBuilder();
HighlightBuilder.Field highlightTitle = new HighlightBuilder.Field("_title1"); //突出显示字段1
highlightTitle.highlighterType("_type"); #突出显示类型
highlightBuilder.field(highlightTitle);
HighlightBuilder.Field highlightUser = new HighlightBuilder.Field("_title2"); //突出显示字段2
highlightBuilder.field(highlightUser);
highlightBuilder.preTags("<b>", "<code>"); //设置高亮前缀
highlightBuilder.postTags("</b>", "</code>"); //设置高亮后缀
highlightUser.noMatchSize(500); //不超过500
searchSourceBuilder.highlighter(highlightBuilder);
  1. 聚合
1
2
3
4
5
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
TermsAggregationBuilder aggregation = AggregationBuilders.terms("_aggsName").field("company.keyword"); //自定义查询的terms名称和filed字段
aggregation.subAggregation(AggregationBuilders.avg("average_age")
.field("age")); //自定义子查询的terms名称和filed字段
searchSourceBuilder.aggregation(aggregation);
1
2
3
4
5
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SuggestionBuilder termSuggestionBuilder = SuggestBuilders.termSuggestion("user").text("kmichy");
SuggestBuilder suggestBuilder = new SuggestBuilder();
suggestBuilder.addSuggestion("suggest_user", termSuggestionBuilder);
searchSourceBuilder.suggest(suggestBuilder);

下面以一个典型的例子作为演示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//    "aggs": {
// "byCategory": {
// "terms": {
// "field": "information_type"
// }
// },
// "bySource": {
// "terms": {
// "field": "source"
// }
// }
// }

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
TermsAggregationBuilder categoryAggregationBuilder = AggregationBuilders.terms("byCategory").field("information_type");
TermsAggregationBuilder sourceAggregationBuilder = AggregationBuilders.terms("bySource").field("source");

searchSourceBuilder.aggregation(categoryAggregationBuilder).aggregation(sourceAggregationBuilder);//同层 //sourceBuilder.aggregation(categoryAggregationBuilder.subAggregation(sourceAggregationBuilder));//嵌套子层

SearchRequest searchRequest = new SearchRequest("_index");
searchRequest.types("_type");
searchRequest.source(searchSourceBuilder);

  1. 分析查询与聚合
    1
    2
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    searchSourceBuilder.profile(true); #可用于简单查询和聚集的分析

同步执行

1
SearchResponse searchResponse = client.search(searchRequest);

异步执行

1
2
3
4
5
6
7
8
9
10
ActionListener<SearchResponse> listener = new ActionListener<SearchResponse>() {
@Override
public void onResponse(SearchResponse searchResponse) { #执行完成时调用
}

@Override
public void onFailure(Exception e) { #执行失败时调用
}
};
client.searchAsync(searchRequest,listener);

查询响应

  1. 响应的状态及类型:
1
2
3
4
5
6
7
8
9
10
11
RestStatus status = searchResponse.status();
TimeValue took = searchResponse.getTook();
Boolean terminatedEarly = searchResponse.isTerminatedEarly();
boolean timedOut = searchResponse.isTimedOut();

int totalShards = searchResponse.getTotalShards();
int successfulShards = searchResponse.getSuccessfulShards();
int failedShards = searchResponse.getFailedShards();
for (ShardSearchFailure failure : searchResponse.getShardFailures()) {
// failures should be handled here
}
  1. 获取数据:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
SearchHits hits = searchResponse.getHits();       //获取响应的hits
long totalHits = hits.getTotalHits(); //获取查询的总数
float maxScore = hits.getMaxScore();

SearchHit[] searchHits = hits.getHits(); //对每一个hits进行轮训操作
for (SearchHit searchHit : searchHits) {
// do something with the SearchHit
String index = searchHit.getIndex(); //获取索引
Map<String, Object> sourceAsMap = searchHit.getSourceAsMap(); //获取数据
// List<Map<String, Object>> mapList = (List<Map<String, Object>>) sourceAsMap.get("_type"); //获取某一个类别,该操作主要用于操作一个list集合
// for(Map<String, Object> map : mapList){
// String value = (boolean) map.get("_key"); //获取某一个字段值
// }
String value = sourceAsMap.get("source"); //获取某一个字段值
}
//列出,一些常见的操作
String index = searchHit.getIndex(); //获取hit的一些信息
String type = searchHit.getType();
String id = searchHit.getId();
float score = searchHit.getScore();

String sourceAsString = searchHit.getSourceAsString();
Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
String documentTitle = (String) sourceAsMap.get("_title");
List<Object> users = (List<Object>) sourceAsMap.get("user");
Map<String, Object> innerObject = (Map<String, Object>) sourceAsMap.get("innerObject");
  1. 检索结果的突出显示
1
2
3
4
5
6
SearchHits hits = searchResponse.getHits();
for (SearchHit searchHit : hits.getHits()) {
Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
HighlightField highlight = highlightFields.get("_title");
String fragmentString = highlight.fragments()[0].string();
}
  1. 检索聚合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Aggregations aggregations = searchResponse.getAggregations();           #从响应里获取聚合
Terms byCompanyAggregation = aggregations.get("_aggsName");
Bucket elasticBucket = byCompanyAggregation.getBucketByKey("Elastic");
Avg averageAge = elasticBucket.getAggregations().get("average_age");
double avg = averageAge.getValue();

Map<String, Aggregation> aggregationMap = aggregations.getAsMap(); #将聚合转换成Map形式
Terms companyAggregation = (Terms) aggregationMap.get("by_company");

List<Aggregation> aggregationList = aggregations.asList();

for (Aggregation agg : aggregations) { #轮训处理
String type = agg.getType();
if (type.equals(TermsAggregationBuilder.NAME)) {
Bucket elasticBucket = ((Terms) agg).getBucketByKey("Elastic");
long numberOfDocs = elasticBucket.getDocCount();
}
}
  1. 检索建议
1
2
3
4
5
6
7
Suggest suggest = searchResponse.getSuggest(); 
TermSuggestion termSuggestion = suggest.getSuggestion("suggest_user");
for (TermSuggestion.Entry entry : termSuggestion.getEntries()) {
for (TermSuggestion.Entry.Option option : entry) {
String suggestText = option.getText().string();
}
}
  1. 检索分析结果
1
2
3
4
5
Map<String, ProfileShardResult> profilingResults = searchResponse.getProfileResults(); 
for (Map.Entry<String, ProfileShardResult> profilingResult : profilingResults.entrySet()) {
String key = profilingResult.getKey();
ProfileShardResult profileShardResult = profilingResult.getValue();
}
文章作者: gqsu
文章链接: http://www.ipdax.com/2018/03/30/elasticsearch-JavaHighLevelRestClient使用/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 技术笔记分享
支付宝打赏
微信打赏