初学JEST操作es6.x的实战

编程

在项目中使用jest操作es6.x(搜索)的心得:

[这篇文章是初学elasticSearch的心得笔记以及遇到的一些问题]

查询方式:

  1. 先创建一个SearchSourceBuilder这个是总的查询对象器

// 主查询条件

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

  1. 在创建一个关于业务逻辑的查询构建器,例如:BoolQueryBuilder 布尔类型的构建器

BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();

  1. 接下来就是对于业务逻辑中各个查询条件的拼接:其实也是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);

}

  1. 将每个过滤条件加入到2中的查询构建器中queryBuilder.must(timeBuilder);
  2. 最后再把2中的queryBuilder放到1中的SearchSourceBuilder中

searchSourceBuilder.query(queryBuilder);

  1. 这个时候可以对总的构建器进行聚合操作

searchSourceBuilder.aggregation(AggregationBuilders

.dateHistogram("aggs")

.field("xxxxxx"));

  1. build之后添加条件,然后发送查询请求(使用JEST)

Search search = new Search.Builder(searchSourceBuilder.toString())

.addType("doc")

.addIndex(index)

.build();

SearchResult result = jestClient.execute(search);

  1. 解析结果 [自己可以点看他有什么解析方法] 这里是解析聚合之后的桶

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

回到顶部