重学Elasticsearch第8章 : SpringBoot整合Jest客户端
文章目录
- JestClient介绍
- 引入依赖
- ES的配置
- (1)、application.yml 配置文件
- (2)、java 连接配置类
- JestClient操作ElasticSearch
- 客户端初始化
- 索引创建
- Mapping创建
- Bulk批量操作
- 单值/多值匹配(term,terms)
- 通配符查询 (wildcardQuery)
- 前缀查询 (prefixQuery)
- Range范围查询
- queryString
- Count(根据条件查询出文档数量)
- 索引和节点操作
- 文档的CRUD
- 查询全部文档(matchAllQuery)
- 分页 (from, size)
- 高亮
- 实体类
- 实战
- 检索操作
- 聚合操作
- 索引信息
官方文档 : https://www.elastic.co/guide/en/elasticsearch/reference/8.3/index.html
JestClient介绍
任何使用过Elasticsearch的人都知道,使用基于rest的搜索API构建查询可能是单调乏味且容易出错的。
Jest,一个用于Elasticsearch的HTTP Java客户端。Elasticsearch提供了自己原生的Java客户端,然而 Jest提供了更流畅的API和更容易使用的接口。
JestClient非官方提供的ES客户端, 现在该客户端已经不再维护, 所以我们主要还是使用RestHighLevelClient
- 由于博主有个项目中采用的客户端是Jest, 所以基于ES系列的完整性, 将这种JestClient的API也记录一下
引入依赖
<!-- JEST -->
<dependency><groupId>io.searchbox</groupId><artifactId>jest</artifactId><version>6.3.1</version>
</dependency><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.6.2</version>
</dependency>
ES的配置
(1)、application.yml 配置文件
elasticsearch:host: http://127.0.0.1:9200spring:elasticsearch:jest:uris: http://localhost:9200
(2)、java 连接配置类
/*** ES的配置类* ElasticSearchConfig*/
@Configuration
@ConfigurationProperties(prefix = "elasticsearch")
public class JestClientConfig {private String host;@Beanpublic JestClient jestClient() {JestClientFactory factory = new JestClientFactory();factory.setHttpClientConfig(new HttpClientConfig.Builder("http://localhost:9200").multiThreaded(true).defaultMaxTotalConnectionPerRoute(2).maxTotalConnection(10).build());return factory.getObject();}
}
JestClient操作ElasticSearch
客户端初始化
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import io.searchbox.core.SearchResult.Hit;
import io.searchbox.core.Suggest;
import io.searchbox.core.SuggestResult;
import io.searchbox.core.Update;import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;import cn.xgs.entity.CsdnBlog;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;import io.searchbox.client.JestClient;
import io.searchbox.client.JestClientFactory;
import io.searchbox.client.JestResult;
import io.searchbox.client.config.HttpClientConfig;
import io.searchbox.cluster.Health;
import io.searchbox.cluster.NodesInfo;
import io.searchbox.cluster.NodesStats;
import io.searchbox.core.Bulk;
import io.searchbox.core.Count;
import io.searchbox.core.CountResult;
import io.searchbox.core.Delete;
import io.searchbox.core.DocumentResult;
import io.searchbox.core.Get;
import io.searchbox.core.Index;
import io.searchbox.core.Search;
import io.searchbox.core.SearchResult;
import io.searchbox.indices.ClearCache;
import io.searchbox.indices.CloseIndex;
import io.searchbox.indices.CreateIndex;
import io.searchbox.indices.DeleteIndex;
import io.searchbox.indices.Flush;
import io.searchbox.indices.IndicesExists;
import io.searchbox.indices.Optimize;
import io.searchbox.indices.mapping.PutMapping;/*** Elasticserach jestClient示例**/
public class Jest {private static JestClient jestClient;private static String indexName = "article"; @Beforepublic void getClient() throws Exception{System.out.println("连接");JestClientFactory factory = new JestClientFactory(); factory.setHttpClientConfig(new HttpClientConfig .Builder("http://192.168.189.138:9200") .gson(new GsonBuilder().setDateFormat("yyyy-MM-dd'T'hh:mm:ss").create()) .connTimeout(1500) .readTimeout(3000) .multiThreaded(true) .build());jestClient=factory.getObject();}@Afterpublic void tearDown() throws Exception { closeJestClient(jestClient); } /** * 关闭JestClient客户端 * @param jestClient * @throws Exception */ public void closeJestClient(JestClient jestClient) throws Exception { if (jestClient != null) { System.out.println("关闭");jestClient.shutdownClient(); } }
}
索引创建
/*** 创建索引* @throws Exception*/
@Test
public void createIndex() throws Exception {JestResult jr = jestClient.execute(new CreateIndex.Builder(indexName).build()); System.out.println(jr.isSucceeded());
}
Mapping创建
/*** Put映射 * @throws Exception*/
@Test
public void createIndexMapping() throws Exception { String source = "{\"" + typeName + "\":{\"properties\":{" + "\"author\":{\"type\":\"string\",\"index\":\"not_analyzed\"}" + ",\"title\":{\"type\":\"string\"}"+ ",\"content\":{\"type\":\"string\"}"+ ",\"price\":{\"type\":\"string\"}"+ ",\"view\":{\"type\":\"string\"}"+ ",\"tag\":{\"type\":\"string\"}"+ ",\"date\":{\"type\":\"date\",\"format\":\"yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis\"}" + "}}}"; System.out.println(source); PutMapping putMapping = new PutMapping.Builder(indexName, typeName, source).build(); JestResult jr = jestClient.execute(putMapping); System.out.println(jr.isSucceeded());
}
Bulk批量操作
/*** Bulk插入数据* @throws IOException */
@Test
public void bulkIndex() throws IOException{CsdnBlog csdnBlog1=new CsdnBlog();csdnBlog1.setAuthor("1111");csdnBlog1.setTitile("中国获租巴基斯坦瓜达尔港2000亩土地 为期43年");csdnBlog1.setContent("据了解,瓜达尔港务局于今年6月完成了1500亩土地的征收工作,另外500亩的征收工作也将很快完成");csdnBlog1.setDate(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(new Date()));csdnBlog1.setView("100");csdnBlog1.setTag("JAVA,ANDROID,C++,LINUX");CsdnBlog csdnBlog2=new CsdnBlog();csdnBlog2.setAuthor("2222");csdnBlog2.setTitile("中国获租巴基斯坦瓜达尔港2000亩土地 为期43年");csdnBlog2.setContent("据了解,瓜达尔港务局于今年6月完成了1500亩土地的征收工作,另外500亩的征收工作也将很快完成");csdnBlog2.setDate(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(new Date()));csdnBlog2.setView("200");csdnBlog2.setTag("ANDROID,C++,LINUX");CsdnBlog csdnBlog3=new CsdnBlog();csdnBlog3.setAuthor("3333");csdnBlog3.setTitile("中国获租巴基斯坦瓜达尔港2000亩土地 为期43年");csdnBlog3.setContent("据了解,瓜达尔港务局于今年6月完成了1500亩土地的征收工作,另外500亩的征收工作也将很快完成");csdnBlog3.setDate(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(new Date()));csdnBlog3.setView("300");csdnBlog3.setTag("JAVA,ANDROID,C++,LINUX");CsdnBlog csdnBlog4=new CsdnBlog();csdnBlog4.setAuthor("4444");csdnBlog4.setTitile("中国获租巴基斯坦瓜达尔港2000亩土地 为期43年");csdnBlog4.setContent("据了解,瓜达尔港务局于今年6月完成了1500亩土地的征收工作,另外500亩的征收工作也将很快完成");csdnBlog4.setDate(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(new Date()));csdnBlog4.setView("400");csdnBlog4.setTag("JAVA,ANDROID,C++,LINUX");Bulk bulk = new Bulk.Builder().defaultIndex(indexName).defaultType(indexName).addAction(Arrays.asList(new Index.Builder(csdnBlog1).build(),new Index.Builder(csdnBlog2).build(),new Index.Builder(csdnBlog3).build(),new Index.Builder(csdnBlog4).build())).build();JestResult jestResult=jestClient.execute(bulk);System.out.println(jestResult.getJsonString());}
单值/多值匹配(term,terms)
/*** 单值完全匹配查询* @throws Exception*/
@Test
public void termQuery() throws Exception { SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); // 检索字段author的值为aaaa的文档QueryBuilder queryBuilder = QueryBuilders.termQuery("author", "aaaa");//单值完全匹配查询 searchSourceBuilder.query(queryBuilder); // 分页searchSourceBuilder.size(10); searchSourceBuilder.from(0); String query = searchSourceBuilder.toString(); System.out.println(query); // 打印的就是DSLSearch search = new Search.Builder(query).addIndex(indexName).build(); SearchResult result = jestClient.execute(search); List<Hit<Object, Void>> hits = result.getHits(Object.class); System.out.println("Size:" + hits.size()); for (Hit<Object, Void> hit : hits) { Object news = hit.source; System.out.println(news.toString()); }
} /*** 多值完全匹配查询 * @throws Exception*/
@Test
public void termsQuery() throws Exception { SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); // 检索字段author的值为1111或2222的文档QueryBuilder queryBuilder = QueryBuilders .termsQuery("author", new String[]{ "1111", "2222" });//多值完全匹配查询 searchSourceBuilder.query(queryBuilder); searchSourceBuilder.size(10); searchSourceBuilder.from(0); String query = searchSourceBuilder.toString(); System.out.println(query);Search search = new Search.Builder(query) .addIndex(indexName) .addType(indexName) .build(); SearchResult result = jestClient.execute(search); List<Hit<Object, Void>> hits = result.getHits(Object.class); System.out.println("Size:" + hits.size()); for (Hit<Object, Void> hit : hits) { Object news = hit.source; System.out.println(news.toString()); }
}
通配符查询 (wildcardQuery)
/*** 通配符和正则表达式查询 * @throws Exception*/
@Test
public void wildcardQuery() throws Exception { SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); QueryBuilder queryBuilder = QueryBuilders .wildcardQuery("title", "*:*");//通配符和正则表达式查询 searchSourceBuilder.query(queryBuilder); searchSourceBuilder.size(10); searchSourceBuilder.from(0); String query = searchSourceBuilder.toString(); System.out.println(query);Search search = new Search.Builder(query) .addIndex(indexName) .build(); SearchResult result = jestClient.execute(search); List<Hit<Object, Void>> hits = result.getHits(Object.class); System.out.println("Size:" + hits.size()); for (Hit<Object, Void> hit : hits) { Object news = hit.source; System.out.println(news.toString()); }
}
前缀查询 (prefixQuery)
/*** 前缀查询* @throws Exception*/
@Test
public void prefixQuery() throws Exception { SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); // 字段author的值, 前缀为11的文档QueryBuilder queryBuilder = QueryBuilders .prefixQuery("author", "11");//前缀查询 searchSourceBuilder.query(queryBuilder); searchSourceBuilder.size(10); searchSourceBuilder.from(0); String query = searchSourceBuilder.toString(); System.out.println(query); Search search = new Search.Builder(query) .addIndex(indexName) .addType(indexName) .build(); SearchResult result = jestClient.execute(search); List<Hit<Object, Void>> hits = result.getHits(Object.class); System.out.println("Size:" + hits.size()); for (Hit<Object, Void> hit : hits) { Object news = hit.source; System.out.println(news.toString()); }
}
Range范围查询
/*** 区间查询 * @throws Exception*/
@Test
public void rangeQuery() throws Exception { SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); QueryBuilder queryBuilder = QueryBuilders .rangeQuery("date") .gte("2019-02-20T15:43:48") .lte("2019-02-20T15:55:45") .includeLower(true) .includeUpper(true);//是否包含区间两边 searchSourceBuilder.query(queryBuilder); searchSourceBuilder.size(10); searchSourceBuilder.from(0); String query = searchSourceBuilder.toString(); System.out.println(query); Search search = new Search.Builder(query) .addIndex(indexName) .addType(indexName) .build(); SearchResult result = jestClient.execute(search); List<Hit<Object, Void>> hits = result.getHits(Object.class); System.out.println("Size:" + hits.size()); for (Hit<Object, Void> hit : hits) { Object news = hit.source; System.out.println(news.toString()); }
}
queryString
/*** 文本检索,应该是将查询的词先分成词库中存在的词,然后分别去检索,存在任一存在的词即返回,查询词分词后是OR的关系。需要转义特殊字符 * @throws Exception*/
@Test
public void queryString() throws Exception { SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); // 文本检索,应该是将查询的词先分成词库中存在的词,然后分别去检索,存在任一存在的词即返回,查询词分词后是OR的关系。// 会对华为手机进行分词,没有设置检索的field,默认对mapping中字符串类型的filed进行检索; QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("华为手机").filed("author").defaultOperator(Operator.AND);;searchSourceBuilder.query(queryBuilder); searchSourceBuilder.size(10); searchSourceBuilder.from(0); String query = searchSourceBuilder.toString(); System.out.println(query);Search search = new Search.Builder(query) .addIndex(indexName) .addType(typeName) .build(); SearchResult result = jestClient.execute(search); List<Hit<Object, Void>> hits = result.getHits(Object.class); System.out.println("Size:" + hits.size()); for (Hit<Object, Void> hit : hits) { Object news = hit.source; System.out.println(news.toString()); }
}
Count(根据条件查询出文档数量)
/*** Count文档 * @throws Exception*/
@Test
public void count() throws Exception { String[] name = new String[]{ "1111", "2222" }; String from = "2019-02-20T15:43:48"; String to = "2019-02-20T15:59:48"; SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); QueryBuilder queryBuilder = QueryBuilders.boolQuery() .must(QueryBuilders.termsQuery("author", name)) .must(QueryBuilders.rangeQuery("date").gte(from).lte(to)); searchSourceBuilder.query(queryBuilder); String query = searchSourceBuilder.toString(); System.out.println(query); Count count = new Count.Builder() .addIndex(indexName) .addType(indexName) .query(query) .build(); CountResult results = jestClient.execute(count); Double counts = results.getCount();System.out.println("Count:" + counts);
}
索引和节点操作
/*** 删除索引* @throws Exception*/@Test public void deleteIndex() throws Exception { JestResult jr = jestClient.execute(new DeleteIndex.Builder(indexName).build()); boolean result = jr.isSucceeded(); System.out.println(result); }/*** 将删除所有的索引* @throws Exception*/@Testpublic void deleteIndexAll() throws Exception {DeleteIndex deleteIndex = new DeleteIndex.Builder("article").build();JestResult result = jestClient.execute(deleteIndex);System.out.println(result.getJsonString());}/*** 清缓存* @throws Exception*/@Testpublic void clearCache() throws Exception {ClearCache closeIndex = new ClearCache.Builder().build();JestResult result = jestClient.execute(closeIndex);System.out.println(result.getJsonString());}/*** 关闭索引* @throws Exception*/@Testpublic void closeIndex() throws Exception {CloseIndex closeIndex = new CloseIndex.Builder("article").build(); JestResult result = jestClient.execute(closeIndex);System.out.println(result.getJsonString());}/*** 优化索引* @throws Exception*/@Testpublic void optimize() throws Exception {Optimize optimize = new Optimize.Builder().build(); JestResult result = jestClient.execute(optimize);System.out.println(result.getJsonString());}/*** 刷新索引* @throws Exception*/@Testpublic void flush() throws Exception {Flush flush = new Flush.Builder().build(); JestResult result = jestClient.execute(flush);System.out.println(result.getJsonString());}/*** 判断索引目录是否存在* @throws Exception*/@Testpublic void indicesExists() throws Exception {IndicesExists indicesExists = new IndicesExists.Builder("article").build();JestResult result = jestClient.execute(indicesExists);System.out.println(result.getJsonString());}/*** 查看节点信息* @throws Exception*/@Testpublic void nodesInfo() throws Exception {NodesInfo nodesInfo = new NodesInfo.Builder().build();JestResult result = jestClient.execute(nodesInfo);System.out.println(result.getJsonString());}/*** 查看集群健康信息* @throws Exception*/@Testpublic void health() throws Exception {Health health = new Health.Builder().build();JestResult result = jestClient.execute(health);System.out.println(result.getJsonString());}/*** 节点状态* @throws Exception*/@Testpublic void nodesStats() throws Exception {NodesStats nodesStats = new NodesStats.Builder().build();JestResult result = jestClient.execute(nodesStats);System.out.println(result.getJsonString());}
文档的CRUD
/*** 更新Document* @param index* @param type* @param id* @throws Exception*/@Testpublic void updateDocument() throws Exception {CsdnBlog article = new CsdnBlog();article.setTitile("中国3333颗卫星拍到阅兵现场高清照");article.setContent("据中国资源卫星应用中心报道,9月3日,纪念中国人民抗日战争暨世界反法西斯战争胜利70周年大阅兵在天安门广场举行。资源卫星中心针对此次盛事,综合调度在轨卫星,9月1日至3日连续三天持续观测首都北京天安门附近区域,共计安排5次高分辨率卫星成像。在阅兵当日,高分二号卫星、资源三号卫星及实践九号卫星实现三星联合、密集观测,捕捉到了阅兵现场精彩瞬间。为了保证卫星准确拍摄天安门及周边区域,提高数据处理效率,及时制作合格的光学产品,资源卫星中心运行服务人员从卫星观测计划制定、复核、优化到系统运行保障、光学产品图像制作,提前进行了周密部署,并拟定了应急预案,为圆满完成既定任务奠定了基础。");article.setDate(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(new Date()));article.setAuthor("匿名");article.setView("110");article.setTag("java,android");String script = "{" +" \"doc\" : {" +" \"titile\" : \""+article.getTitile()+"\"," +" \"content\" : \""+article.getContent()+"\"," +" \"author\" : \""+article.getAuthor()+"\"," +" \"view\" : \""+article.getView()+"\"," +" \"tag\" : \""+article.getTag()+"\"," +" \"date\" : \""+article.getDate()+"\"" +" }" +"}";Update update = new Update.Builder(script).index(indexName).type(indexName).id("pUTcCWkBKPh010MkRo9h").build();JestResult result = jestClient.execute(update);System.out.println(result.getJsonString());}/*** 删除Document* @param index* @param type* @param id* @throws Exception*/@Testpublic void deleteDocument() throws Exception {Delete delete = new Delete.Builder("").index(indexName).type(typeName).build();JestResult result = jestClient.execute(delete);System.out.println(result.getJsonString());}/*** 获取Document* @param index* @param type* @param id* @throws Exception*/@Testpublic void getDocument() throws Exception {Get get = new Get.Builder(indexName,"").type(indexName).build();JestResult result = jestClient.execute(get);CsdnBlog article = result.getSourceAsObject(CsdnBlog.class);System.out.println(article.getTitile()+","+article.getContent());}
查询全部文档(matchAllQuery)
/*** 查询全部* @throws Exception*/@Test
public void searchAll() throws Exception {SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();searchSourceBuilder.query(QueryBuilders.matchAllQuery());Search search = new Search.Builder(searchSourceBuilder.toString()).addIndex(indexName).build();SearchResult result = jestClient.execute(search);System.out.println("本次查询共查到:"+result.getTotal()+"篇文章!");List<Hit<CsdnBlog,Void>> hits = result.getHits(CsdnBlog.class);for (Hit<CsdnBlog, Void> hit : hits) {CsdnBlog source = hit.source;System.out.println("标题:"+source.getTitile());System.out.println("内容:"+source.getContent());System.out.println("浏览数:"+source.getView());System.out.println("标签:"+source.getTag());System.out.println("作者:"+source.getAuthor());}
}
分页 (from, size)
/*** 分页* @throws IOException */
@Test
public void page() throws IOException{int pageNumber=1;int pageSize=10;SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();searchSourceBuilder.query(QueryBuilders.queryStringQuery("zshuai"));searchSourceBuilder.from((pageNumber - 1) * pageSize);//设置起始页searchSourceBuilder.size(pageSize);//设置页大小Search search = new Search.Builder(searchSourceBuilder.toString()).addIndex(indexName)// 索引名称.build();SearchResult result = jestClient.execute(search);// 自动解析JsonObject jsonObject = result.getJsonObject();JsonObject hitsobject = jsonObject.getAsJsonObject("hits");long took = jsonObject.get("took").getAsLong();long total = hitsobject.get("total").getAsLong();System.out.println("took:"+took+" "+"total:"+total);
}
高亮
/*** 搜索高亮显示* @throws Exception*/@Testpublic void createSearch() throws Exception {SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();searchSourceBuilder.query(QueryBuilders.termQuery("view", "200"));HighlightBuilder highlightBuilder = new HighlightBuilder();highlightBuilder.field("view");//高亮titlehighlightBuilder.preTags("<em>").postTags("</em>");//高亮标签highlightBuilder.fragmentSize(500);//高亮内容长度searchSourceBuilder.highlighter(highlightBuilder);System.out.println(searchSourceBuilder.toString());Search search = new Search.Builder(searchSourceBuilder.toString()).addIndex(indexName).build();SearchResult result = jestClient.execute(search);System.out.println(result.getJsonString());System.out.println("本次查询共查到:"+result.getTotal()+"篇文章!");List<Hit<CsdnBlog,Void>> hits = result.getHits(CsdnBlog.class);System.out.println(hits.size());for (Hit<CsdnBlog, Void> hit : hits) {CsdnBlog source = hit.source;//获取高亮后的内容Map<String, List<String>> highlight = hit.highlight;List<String> views = highlight.get("view");//高亮后的titleif(views!=null){source.setView(views.get(0));}System.out.println("标题:"+source.getTitile());System.out.println("内容:"+source.getContent());System.out.println("浏览数:"+source.getView());System.out.println("标签:"+source.getTag());System.out.println("作者:"+source.getAuthor());}
}
实体类
package cn.xgs.entity;public class CsdnBlog {private String author;private String titile;private String tag;private String content;private String view;private String date;public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public String getTitile() {return titile;}public void setTitile(String titile) {this.titile = titile;}public String getTag() {return tag;}public void setTag(String tag) {this.tag = tag;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public String getView() {return view;}public void setView(String view) {this.view = view;}public String getDate() {return date;}public void setDate(String date) {this.date = date;}public CsdnBlog(String author, String titile, String tag, String content, String view, String date) {super();this.author = author;this.titile = titile;this.tag = tag;this.content = content;this.view = view;this.date = date;}public CsdnBlog() {super();// TODO Auto-generated constructor stub}
}
实战
检索操作
@Builder
@Data
public class PageableResult<T> {private Pageable page;private List<T> data;
}@Service
@Slf4j
public class EsServiceImpl {public PageableResult<EsHLog> searchLogList(LogSearchReq req) throws IOException {SearchSourceBuilder builder = new SearchSourceBuilder();BoolQueryBuilder boolQuery = createBuilder(req);builder.query(boolQuery).from((req.getPageIndex() - 1) * req.getPageSize()).size(req.getPageSize()).sort("logTime", req.getTimeSortFlag() != null && req.getTimeSortFlag() ? SortOrder.ASC : SortOrder.DESC).fetchSource(true).timeout(TimeValue.timeValueMinutes(2));SearchResult searchResult = (SearchResult) this.execute(req.getAppId(), null, builder, req.getEndTime(), null);PageableResult<EsHLog> result = this.convertPageableResult(searchResult, this::convert);result.getPage().setPageIndex(req.getPageIndex());result.getPage().setPageSize(req.getPageSize());return result;}private BoolQueryBuilder createBuilder(LogSearchReq req) {BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();//1、appIdTermQueryBuilder appQuery = QueryBuilders.termQuery("appId", req.getAppId());boolQuery.filter(appQuery);//envTermQueryBuilder envQuery = QueryBuilders.termQuery("env", env);boolQuery.filter(envQuery);//2、timeRangeQueryBuilder timeQuery = QueryBuilders.rangeQuery("logTime").from(req.getStartTime()).includeLower(true).to(req.getEndTime()).includeUpper(true);boolQuery.filter(timeQuery);//3、titleif (StringUtils.isNotBlank(req.getTitle())) {QueryStringQueryBuilder titleQuery = QueryBuilders.queryStringQuery(req.getTitle()).field("title").defaultOperator(Operator.AND);//by default, match with ANDboolQuery.filter(titleQuery);}//4、log levelif (CollectionUtils.isNotEmpty(req.getLevels())) {TermsQueryBuilder levelQuery = QueryBuilders.termsQuery("level", req.getLevels());boolQuery.filter(levelQuery);}//5、tagsif (StringUtils.isNotBlank(req.getTags())) {if (req.getTags().contains(";") || !req.getTags().contains(":")) {String[] split = req.getTags().split(";");TermsQueryBuilder tagsQuery = QueryBuilders.termsQuery("tags", Arrays.asList(split));boolQuery.filter(tagsQuery);} else {String[] tags = req.getTags().split(":");for (String tag : tags) {TermsQueryBuilder tagsQuery = QueryBuilders.termsQuery("tags", tag);boolQuery.filter(tagsQuery);}}}//6、contentif (StringUtils.isNotBlank(req.getContent())) {QueryStringQueryBuilder messageQuery = QueryBuilders.queryStringQuery(req.getContent()).field("fullMessage").defaultOperator(Operator.AND);//by default, match with ANDboolQuery.filter(messageQuery);}//7、machineif (CollectionUtils.isNotEmpty(req.getMachines())) {TermsQueryBuilder machineQuery = QueryBuilders.termsQuery("machine", req.getMachines());boolQuery.filter(machineQuery);}//8、ipif (CollectionUtils.isNotEmpty(req.getIps())) {TermsQueryBuilder ipQuery = QueryBuilders.termsQuery("machineIp", req.getIps());boolQuery.filter(ipQuery);}//9、traceIdif (StringUtils.isNotBlank(req.getTraceId())) {TermQueryBuilder traceQuery = QueryBuilders.termQuery("traceId", req.getTraceId());boolQuery.filter(traceQuery);}//10、logNameif (StringUtils.isNotBlank(req.getLogName())) {TermQueryBuilder logNameQuery = QueryBuilders.termQuery("logName", req.getLogName());boolQuery.filter(logNameQuery);}if (StringUtils.isNotBlank(req.getPattern())) {TermQueryBuilder patternQuery = QueryBuilders.termQuery("pattern", req.getPattern());boolQuery.filter(patternQuery);}if (StringUtils.isNotBlank(req.getMessageSize())) {ExistsQueryBuilder messageSize = QueryBuilders.existsQuery("messageSize");boolQuery.filter(messageSize);RangeQueryBuilder gteQuery = QueryBuilders.rangeQuery("messageSize").gte(req.getMessageSize());boolQuery.filter(gteQuery);}if (StringUtils.isNotBlank(req.getUnitRouteCode())) {TermQueryBuilder routeCodeQuery = QueryBuilders.termQuery("routeCode", req.getUnitRouteCode());boolQuery.filter(routeCodeQuery);}return boolQuery;}private JestResult execute(String appId, Long time, SearchSourceBuilder builder,LocalDateTime queryEndTime, String esCluster) throws IOException {JestClient jestClient = EsApplication.getInstance().getJestClient(StringUtils.isNotBlank(esCluster) ? esCluster :getCluster(appId, queryEndTime)); // 集群名SearchResult result = jestClient.execute(new Search.Builder(builder.toString())// 索引名.addIndex(getIndex(appId, time)).build());return result;}/*** convert search result*/private <R> PageableResult<R> convertPageableResult(SearchResult searchResult, Function<SearchResult.Hit<EsHLog, Void>, R> converter) {Pageable page = new Pageable();page.setTotalCount(getTotal(searchResult));List<SearchResult.Hit<EsHLog, Void>> hits = searchResult.getHits(EsHLog.class, false);return PageableResult.<R>builder().page(page).data(Optional.ofNullable(hits).orElse(new ArrayList<>()).stream().map(hit -> converter.apply(hit)).collect(Collectors.toList())).build();}
}
聚合操作
public List<MachineEntity> searchMachineList(String appId, LocalDateTime startTime, LocalDateTime endTime) throws IOException {SearchSourceBuilder builder = new SearchSourceBuilder();BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();//1、appIdTermQueryBuilder appQuery = QueryBuilders.termQuery("appId", appId);//envTermQueryBuilder envQuery = QueryBuilders.termQuery("env", env);boolQuery.filter(envQuery);//2、timeRangeQueryBuilder timeQuery = QueryBuilders.rangeQuery("logTime").from(startTime).includeLower(true).to(endTime).includeUpper(true);boolQuery.filter(appQuery).filter(timeQuery);//3、machine aggTermsAggregationBuilder machineAgg = AggregationBuilders.terms("agg_by_machine").field("machine").size(Integer.MAX_VALUE);builder.query(boolQuery).aggregation(machineAgg).fetchSource(false).size(0).timeout(TimeValue.timeValueMinutes(1));SearchResult searchResult = (SearchResult) this.execute(appId, null, builder, endTime, null);MetricAggregation aggregations = searchResult.getAggregations();TermsAggregation machineAggResult = aggregations.getTermsAggregation("agg_by_machine");return this.convertTermsAggResult(machineAggResult, bucket -> {MachineEntity machine = MachineEntity.builder().label(bucket.getKey()).name(bucket.getKey()).build();return machine;});}private JestResult execute(String appId, Long time, SearchSourceBuilder builder,LocalDateTime queryEndTime, String esCluster) throws IOException {JestClient jestClient = EsApplication.getInstance().getJestClient(StringUtils.isNotBlank(esCluster) ? esCluster :getCluster(appId, queryEndTime)); // 集群名SearchResult result = jestClient.execute(new Search.Builder(builder.toString())// 索引名.addIndex(getIndex(appId, time)).build());return result;}/*** convert terms aggregation** @return*/protected <R> List<R> convertTermsAggResult(TermsAggregation termsAgg, Function<TermsAggregation.Entry, R> converter) {if (termsAgg != null && CollectionUtils.isNotEmpty(termsAgg.getBuckets())) {return termsAgg.getBuckets().stream().map(converter).collect(Collectors.toList());}return new ArrayList<>(0);}
索引信息
public class searchIndexMsg(LocalDate localDate) throws IOException {String indexDate = DateUtil.format(DateTimeUtils.toDate(localDate), PURE_DATE_FORMAT);Cat.IndicesBuilder indicesBuilder = new Cat.IndicesBuilder().setParameter("bytes", "mb");CatResult result = executeByCat(indexDate, indicesBuilder, cluster);private CatResult executeByCat(String indexDate, Cat.IndicesBuilder builder, String esCluster) throws IOException {if(StringUtils.isBlank(esCluster)){return null;}JestClient jestClient = EsApplication.getInstance().getJestClient(esCluster);return jestClient.execute(builder.addIndex(getIndexByCat(indexDate)).build());}
}
重学Elasticsearch第8章 : SpringBoot整合Jest客户端相关推荐
- 重学Elasticsearch第6章 : SpringBoot整合RestHighLevelClient
文章目录 RestHighLevelClient介绍 引入依赖 ES的配置 (1).创建索引 (2).application.yml 配置文件 (3).实体对象 (4).java 连接配置类 索引操作 ...
- 重学Elasticsearch第1章 : Elasticsearch, Kibana概念、Elasticsearch相关术语
文章目录 Elastic Stack 是什么 ElasticSearch 概念 什么是RestFul 什么是全文检索 什么是Elasticsearch ES的应用场景 安装Elasticsearch ...
- 关于SpringBoot整合Netty客户端和服务端实现JT808协议
关于SpringBoot整合Netty客户端和服务端实现JT808协议 最近做了一个使用netty实现交通部JT808协议的项目,对比了mina和netty两种框架的使用,先整理一下netty的实现过 ...
- SpringBoot整合Redis客户端
一.SpringBoot整合Redis的步骤 1. 导入SpringBoot整合Redis坐标,starter <dependency><groupId>org.springf ...
- 第九章SpringBoot整合Spring Data JPA
目录 1 概述 2 Spring Data JPA整合 2.1 pom文件 2.2 配置文件 2.3 实体类 2.4 Dao接口 2.5 启动类 2.6 编写测试类 3 Spring Data JPA ...
- ElasticSearch(三)springboot整合ES
最基础的整合: 一.maven依赖 <parent><groupId>org.springframework.boot</groupId><artifactI ...
- 重学JavaSE 第12章 : 枚举和注解、注解的实战使用
文章目录 一.枚举类的使用 1.1.枚举类的理解 1.2.自定义枚举类 1.3.使用enum关键字定义枚举类 1.4.Enum类中的常用方法 1.5.使用enum关键字定义的枚举类实现接口 二.注解的 ...
- 重学JavaSE 第4章 : 顺序结构、分支语句、循环结构、break, continue, return区别
文章目录 一. 程序流程控概述 二. 顺序结构 三.分支语句 2.1.分支语句1:if-else结构 2.1.1.输入语句 2.2. 分支语句2:switch-case结构 四.循环结构 4.1.fo ...
- 重学JavaSE 第11章 : 常用类API、String、日期API、比较器、BigDecimal、System等
文章目录 一.字符串相关的类 1.1.String类的概述 1.2.理解String的不可变性 1.3.String不同实例化方式的对比 1.4.String不同拼接操作的对比 1.4.1.Strin ...
最新文章
- 网站防火墙探测工具Wafw00f
- bs架构 mysql_基于BS架构OA办公系统的设计(PHP,MySQL)(三人组)(含录像)
- linux基本知识2
- 文章已转移到“字符集编码与乱码”分类下
- java stub_Java Stub 研究学习(2)
- Linux IPC POSIX 共享内存
- 实录:oracle下大表清理整改
- .NET中三种获取当前路径的代码
- cad插件_CAD插件自动编号安装教程
- Hibernate主键生成策略
- 计算机卡登录界面,win10系统卡在登录界面怎么办 windows10卡在登录界面的解决方法...
- 只要花3K 手把手教你制作炫酷的MR混合现实视频
- 设定软件使用期限,根据网络时间保护试用软件产品的方法
- XML DTD Schema 学习-Schema 介绍
- 快速生成APP的平台
- 神经网络按功能分为几类,神经网络分为几种类型
- 电脑一打开wps就黑屏_打开电脑,显示器黑屏该如何解决?
- IT知名公司工资一览
- 8位MCU跑RTOS有没有意义?
- 基于Metronic的Bootstrap开发框架经验总结
热门文章
- freemarker 循环map里面的对象形式List
- 中国移动举行“移动生活卡”首发仪式
- Ubuntu搭建kms服务器
- 基于java酒店管理系统_课内资源 - 基于JAVA实现的互联网酒店管理系统
- ThinkPHP开发的手册管理系统-文档云(仿看云),可二次开发
- 660测试软件,联发科P60还是骁龙660?联发科P60和骁龙660游戏测试详细对比
- 巴别鸟是如何用2个月时间让上市公司“爱上”它的?
- VS2010+.net4.0仿照苹果手机上的消除之星写了一个电脑版的功能简单 稍后将公开源码(一)
- zoj 1178 Booklet Printing
- 交叉编译出现提示 plugin needed to handle lto object