初学JEST操作es6.x的实战
在项目中使用jest操作es6.x(搜索)的心得:
[这篇文章是初学elasticSearch的心得笔记以及遇到的一些问题]
查询方式:
- 先创建一个SearchSourceBuilder这个是总的查询对象器
// 主查询条件SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
- 在创建一个关于业务逻辑的查询构建器,例如:BoolQueryBuilder 布尔类型的构建器
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
- 接下来就是对于业务逻辑中各个查询条件的拼接:其实也是BoolQueryBulider之类的构建器作为各个过滤条件
// 单个过滤条件BoolQueryBuilder stringBuilder = QueryBuilders.boolQuery();
authBuilder.should(QueryBuilders.termQuery("xxx", "xxx"));
authBuilder.should(QueryBuilders.termQuery("xxx", "xxx"));
queryBuilder.must(authBuilder);
//范围过滤条件
BoolQueryBuilder timeBuilder = QueryBuilders.boolQuery();
long dateOffsetNum = DateUtil.between(start, end, DateUnit.DAY) + 1;
Date endTime = DateUtil.offsetDay(start, Integer.parseInt(StrUtil.toString(dateOffsetNum)));
timeBuilder.should(QueryBuilders.rangeQuery("xxx")
.gte(DateUtil.format(start, DatePattern.NORM_DATETIME_PATTERN))
.lt(DateUtil.format(endTime, DatePattern.NORM_DATETIME_PATTERN))
.format(DatePattern.NORM_DATETIME_PATTERN)
.timeZone(TimeZone.getDefault().getID()));
queryBuilder.must(timeBuilder);
//集合过滤条件
if (list != null && list.size() > 0) {
BoolQueryBuilder listBoolBuilder = QueryBuilders.boolQuery();
listBoolBuilder.must(QueryBuilders
.termsQuery("xxx", list));
queryBuilder.must(listBoolBuilder);
}
- 将每个过滤条件加入到2中的查询构建器中queryBuilder.must(timeBuilder);
- 最后再把2中的queryBuilder放到1中的SearchSourceBuilder中
searchSourceBuilder.query(queryBuilder);
- 这个时候可以对总的构建器进行聚合操作
searchSourceBuilder.aggregation(AggregationBuilders .dateHistogram("aggs")
.field("xxxxxx"));
- build之后添加条件,然后发送查询请求(使用JEST)
Search search = new Search.Builder(searchSourceBuilder.toString()) .addType("doc")
.addIndex(index)
.build();
SearchResult result = jestClient.execute(search);
- 解析结果 [自己可以点看他有什么解析方法] 这里是解析聚合之后的桶
SearchResult result = jestClient.execute(search1);if (result != null && result.isSucceeded()) {
DateHistogramAggregation dateHistogram = result.getAggregations().getDateHistogramAggregation("xxx");
List<DateHistogramAggregation.DateHistogram> buckets = dateHistogram.getBuckets();
list.addAll(buckets.stream().map(Bucket::getCount).collect(Collectors.toList()));
}
存在两种一种是getJsonObject()获得对应的json数据进行本地解析,第二种是用JEST的API使用它们帮助解析。
总结:最后就按照业务逻辑处理数据就好啦,其实es的数据传输本质上都是JSON格式的数据,发送的请求也是RESTFUL风格的请求,很容易进行掌握,剩下的深入学习就是学习对应的api以及聚合分组多聚合的对应操作了。
遇到的难点:
在这次实战中,遇到的难点是对于数据的分组查询速度太慢。
实际场景如下:需要按照自定义时间段来进行数据索引,处理之后的数据格式是按照24小时来显示数据。之前的处理方案是模拟24小时,循环进行24次查询,就是比如查询2020-07-22到2020-07-24的数据 就进行24次查询分别查询每一天的第一个小时然后第二个小时然后加和。
这样经过24次循环调用es查询才能完事,速度上比较慢。
优化1.0
后来,我们经过了讨论,把这个改成2小时查一次,将接口分成两段,由前端先调用0-11的数据,再异步调用12-23的数据,这样速度快上了不少。
优化2.0
再后来我们发现了es6.x按照时间段聚合的方法,多亏了这位 @爆炒八酱 老哥,这是他CSDN的连接
https://blog.csdn.net/qq_28311921/article/details/105077624
我们发现了interval这个字段可以按照时间段分组,于是就修改了代码:
searchSourceBuilder1.aggregation(AggregationBuilders.dateHistogram("date_histogram")
.field("xxx")
.interval(3600000L)
.format("yyyy-MM-dd"));
在聚合的时候按照时间段分组,然后取出他的桶就好啦
if (result != null && result.isSucceeded()) { DateHistogramAggregation dateHistogram = result.getAggregations() .getDateHistogramAggregation("date_histogram");
List<DateHistogramAggregation.DateHistogram> buckets = dateHistogram.getBuckets();
dayList.addAll(buckets.stream().map(Bucket::getCount).collect(Collectors.toList()));
}
去重(使用cardinality关键字去重):
//根据时间间隔小时聚合(去重)searchSourceBuilder.aggregation(
AggregationBuilders.dateHistogram("date_histogram")
.field("xxx")
.interval(3600000L)
.format("yyyy-MM-dd")
.subAggregation(AggregationBuilders.cardinality("cardinality").field("xxx.keyword")));
但是,用这种去重方法jest的DateHistogramAggregation 解析无法解析(他的数据结构多了一个对象格式的字段)所以,就用原始的JSON解析就好啦!
JsonArray asJsonArray = jsonObject.getAsJsonObject("aggs").getAsJsonObject("date_histogram").getAsJsonArray("buckets");List<CardinalityEntity> cardinalityEntities = JSONUtil.toList(JSONUtil.parseArray(asJsonArray.toString()), CardinalityEntity.class);
但是,最终的问题来啦,如果时间范围大于1天,那么返回的桶就是对应的24倍,毕竟他是按照时间段来聚合,而不是按照小时的关键字来聚合,这可很难受,但是在我们小组的大大大佬的帮助下,完美的解决了这个问题。只需要获取返回的时间小时过滤一下,放入map中自己加和,完美的解决速度问题。
总结:
其实学习es一定要了解他的数据结构和相关的操作方法,这样才能在实战中灵活运用,
[这次实战是在小组大佬的帮助下完成的,有人带的感觉就是舒服 嘿嘿]
其实不管用什么操作es的开源框架,首先也是必须条件就是要回自己用原生的api操作,这样才能运用得当,如臂使指。
以上是 初学JEST操作es6.x的实战 的全部内容, 来源链接: utcz.com/z/518788.html