SpringBoot整合Elasticsearch
SpringBoot整合Elasticsearch的API调用示例
一、简介
Elasticsearch 是一个分布式的开源搜索和分析引擎,适用于所有类型的数据,包括文本、数字、地理空间、结构化和非结构化数据。
使用ES检索、搜索、统计数据。简单的使用场景:
1)线上商城系统,用户需要搜索商城上的商品
2)系统需要收集日志,用这些日志来分析、挖掘从而获取系统业务未来的趋势
3)大量数据(数百万甚至数十亿的数据)快速调查、分析并且要将分析结果可视化的需求
二、使用(后续待补充....)
1、pom依赖,注意版本兼容,此处使用springboot的2.2.7.RELEASE版本和es的7.1.0
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.1.0</version>
</dependency>
2、配置
@Configuration public class ElasticSearchConfig { @Bean public RestHighLevelClient restHighLevelClient() { RestHighLevelClient client = new RestHighLevelClient( RestClient.builder(new HttpHost("192.168.xx.xxx", 9200, "http"),new HttpHost("192.168.xx.xxx", 9200, "http"))); return client;//集群建议3台起,不然集群健康值: red/yellow } }
3、调用工具类
@Component public class SpringUtil implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { if(SpringUtil.applicationContext == null) { SpringUtil.applicationContext = applicationContext; } } //获取applicationContext public static ApplicationContext getApplicationContext() { return applicationContext; } //通过name获取 Bean. public static Object getBean(String name) { return getApplicationContext().getBean(name); } //通过class获取Bean. public static <T> T getBean(Class <T> clazz) { return getApplicationContext().getBean(clazz); } //通过name,以及Clazz返回指定的Bean public static <T> T getBean(String name, Class <T> clazz) { return getApplicationContext().getBean(name, clazz); } }
4、工具类调用(基本使用方法调用)
/** * ElasticSearch工具类 * 更多API参考:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.x/java-rest-high.html * */ @Slf4j public class ElasticSearchUtil { RestHighLevelClient client = SpringUtil.getBean(RestHighLevelClient.class); /** * 创建索引 * * @param index 必须小写,格式参考文档 * @return * @author :fuanfei * @date :2020/5/21 */ public boolean createIndex(String index) { CreateIndexResponse response; try { if(!this.existsIndex(index)) { response = client.indices().create(new CreateIndexRequest(index), RequestOptions.DEFAULT); } else { return true;//索引已存在 } } catch(Exception e) { log.error("ElasticSearch 创建索引异常"); return false; } return response.isAcknowledged(); } /** * 删除索引 * * @param index * @return * @author :fuanfei * @date :2020/5/21 */ public boolean delIndex(String index) { AcknowledgedResponse response = null; try { if(this.existsIndex(index)) { client.indices().delete(new DeleteIndexRequest(index), RequestOptions.DEFAULT); } else { return true;//索引不存在 } } catch(Exception e) { log.error("ElasticSearch 删除索引异常,时间->" + LocalDateTime.now()); return false; } return response.isAcknowledged(); } /** * 创建文档 * id相同则更新、不同则创建,数据格式(字段)不同则空,字段为追加模式 * * @param index 索引 * @param data 数据 例:JSON.toJSONString(obj) * @param dataType 格式类型 例:XContentType.JSON * @param id 唯一标识 put /index/_doc/1 * @return */ public int addDocument(String index, String data, XContentType dataType, String id) { IndexRequest request = new IndexRequest(index); request.id(id); request.source(data, dataType); IndexResponse response = null; try { response = client.index(request, RequestOptions.DEFAULT); } catch(Exception e) { log.error("ElasticSearch 创建文档异常,时间->" + LocalDateTime.now()); } return response != null ? response.status().getStatus() : 400; } /** * 获取文档 * * @param index * @param id */ public Map <String, Object> getDocument(String index, String id) { GetResponse getResponse = null; try { if(this.existsIndex(index)) { GetRequest getRequest = new GetRequest(index, id); //getRequest.fetchSourceContext(new FetchSourceContext(false)); //getRequest.storedFields("_none_"); getResponse = client.get(getRequest, RequestOptions.DEFAULT); } } catch(Exception e) { log.error("ElasticSearch 获取文档异常,时间->" + LocalDateTime.now()); } return getResponse != null ? getResponse.getSource() : null; } /** * 更新文档信息 * 备注:更新成功查询不出来可能是改字段不匹配且id标识存在 * * @param index * @param data * @param dataType * @param id * @return */ public int updateDocument(String index, String data, XContentType dataType, String id) { UpdateResponse updateResponse = null; try { if(this.existsIndex(index)) { UpdateRequest updateRequest = new UpdateRequest(index, id); //updateRequest.timeout("1s");//缓冲期 updateRequest.doc(data, dataType); updateResponse = client.update(updateRequest, RequestOptions.DEFAULT); } } catch(Exception e) { log.error("ElasticSearch 更新文档信息异常,时间->" + LocalDateTime.now()); } return updateResponse != null ? updateResponse.status().getStatus() : 400; } /** * 批量操作文档信息 * 备注:暂局限入参list,可扩展其他<?> * * @param index * @param list 标识相同则覆盖,否则新增 * @param dataType * @return */ public boolean addDocumentList(String index, List <Admin> list, XContentType dataType) { BulkRequest bulkRequest = new BulkRequest(); //bulkRequest.timeout("10s");//缓冲期 for(Admin admin : list) { bulkRequest.add(new IndexRequest(index) .id("" + admin.getId())//执行多次貌似会覆盖 .source(JSON.toJSONString(admin), dataType)); } BulkResponse bulk = null; try { bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT); } catch(Exception e) { log.error("ElasticSearch批量操作文档信息异常,时间->" + LocalDateTime.now()); } //false代表成功,所以取反 return bulk != null ? !bulk.hasFailures() : false; } /** * 查询数据 * 备注:可拓展深入精准查询、范围查询、模糊查询、匹配所有等 * @param index * @return */ public List <Map <String, Object>> searchDocument(String index) { SearchRequest searchRequest = new SearchRequest(index); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); MatchAllQueryBuilder termQueryBuilder = QueryBuilders.matchAllQuery(); sourceBuilder.query(termQueryBuilder); // sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); searchRequest.source(sourceBuilder); SearchResponse search; try { search = client.search(searchRequest, RequestOptions.DEFAULT); } catch(Exception e) { log.error("ElasticSearch 查询数据异常,时间->" + LocalDateTime.now()); return null; } SearchHit[] hits = search.getHits().getHits(); List <Map <String, Object>> mapList = new ArrayList <>(); for(SearchHit hit : hits) { mapList.add(hit.getSourceAsMap()); } return mapList; } /** * 判断索引是否存在 * @param index * @return */ private boolean existsIndex(String index) throws IOException { return client.indices().exists(new GetIndexRequest(index), RequestOptions.DEFAULT); } private void close(RestHighLevelClient client) { try { client.close(); } catch(IOException e) { log.error("ElasticSearch 关闭异常"); } } }
5、创建有分片的索引
/** * @param index * @param shards 主分片数量 * @param replicas 副本分片数量 * @return */ public boolean createIndex(String index, int shards, int replicas) { CreateIndexRequest request = new CreateIndexRequest(index); request.settings(Settings.builder() .put("index.number_of_shards", shards) .put("index.number_of_replicas", replicas) ); request.setTimeout(TimeValue.timeValueMinutes(2)); request.setMasterTimeout(TimeValue.timeValueMinutes(1)); CreateIndexResponse response = null; try { if(!this.existsIndex(index)) { response = client.indices().create(request, RequestOptions.DEFAULT); } } catch(Exception e) { log.error("ElasticSearch 创建索引异常"); } return response != null ? response.isAcknowledged() : false; }
-----------------------------------------------------------------------------------
参考官网网址:
客户端API:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.x/java-rest-high-javadoc.html
Elasticsearch SQL旨在为Elasticsearch提供强大而轻量级的SQL接口:https://www.elastic.co/guide/en/elasticsearch/reference/7.8/xpack-sql.html
手册:https://es.quanke.name/
使用感想:ELK实操实在是刷新了对大数据的观念,目前只习得冰山一角,持续学习才是王道。
ES的DLS查询
常用关键字
term(单值过滤)terms(多值过滤)
sort (排序)_source (搜索指定字段)
sum/min/max/avg/cardinality(基数)/percentiles(百分比)、stats(统计)/extended-stats(扩展统计)
PUT /test_data1/ 创建
查询语句 #GET 索引/类型/ID
GET /test_data1/_doc/_search { "query": { "bool": { #where "must": [ #and { "wildcard": { #通配符 ?->_ *->% "dname.keyword": "虚点.热泵机组.1号冷机.?回路排气温度" } }, { "range": { #范围 gt(大于)lt(小于)gte(大于等于)lte(小于等于) "revtime": { "gt": "2019-05-16T18:00:00.000Z", "lt": "2019-05-17T18:30:00.000Z" } } } ], "must_not": [], #not "should": [] #or } }, "from": 0, #从那一页开始 "size": 100, #显示多少行 "aggs": { #聚合 "sum-v": { #名字随意 "sum": { #求什么 "field": "dvalue" } } }
浙公网安备 33010602011771号