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 关闭异常");
        }
    }
}
View Code

 

  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"
}
}
}

 

posted on 2020-06-01 17:55  fuanfei  阅读(288)  评论(0)    收藏  举报