×
广告

SpringBoot集成ElasticSearch

96
我叫钱多多_
2018.09.12 16:57 字数 1192

1. ElasticSearch

1.1 ElasticSearch的简单介绍

ElasticSearch 是开源搜索平台领域的一个新成员。 ElasticSearch(简称 ES) 是一个基于 Lucene 构建的开源,分布式,RESTful 搜索引擎。 具有搜索实时、稳定、可靠和快速的特点,并且安装使用方便。 支持通过 HTTP 请求,使用 JSON 进行数据索引。

1.2 ElasticSearch的一些概念的介绍

(1). 索引: 一个索引就是一个拥有几分相似特征的文档的集合。一个索引由一个名字来标识(必须全部是小写字母的),并且当我们要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。在一个集群中,可以定义任意多的索引。索引名称必须要全部小写,也不能以下划线开头,不能包含逗号。类似于关系型数据库中的数据库;
(2). 类型:在一个索引中,可以定义一种或多种类型。一个类型是你的索引的一个逻辑上的分类/分区,通常,会为具有一组共同字段的文档定义一个类型,每一个类型都拥有自己的映射(mapping)或者结构定义,它们定义了当前类型下的数据结构,类似于数据库表中的列。划分时需要注意一些限制条件,例如不同的文档类型对同一字段不能设置为不同的字段类型;类似于关系型数据库中的的表;
(3). 文档:一个文档是一个可被索引的基础信息单元。文档以JSON(JavascriptObject Notation)格式来表示,一个文档不只包含了数据。它还包含了元数据(metadata) —— 关于文档的信息。有三个元数据元素是必须存在的,它们是:id是一个字符串, _index 和 _type ,他们可以组合起来锁定Elasticsearch中一个特定的文档。

1.3 ElasticSearch与关系型数据库的对照关系

DB -> Databases -> Tables -> Rows -> Columns 
ES -> Indices -> Types -> Documents -> Fields

3.4 ElasticSearch中对索引的一些常用操作

1. 获取Elasticsearch中所有的index:

curl -XGET 'localhost:9200/_cat/indices?v&pretty'

2. 获取某索引下所有的type:

获取elasticsearch索引下所有的type定义
curl -XGET 'localhost:9200/elasticsearch/_mapping'

3. 删除索引:

删除elasticsearch1索引
curl -XDELETE 'localhost:9200/elasticsearch1?pretty'

4. 删除某索引下的某type数据:

删除索引elasticsearch下的article类型
curl -XDELETE 'http://localhost:9200/elasticsearch/article/'

5. 查看某索引的某type下所有的数据:

查找elasticsearch索引中所有的类型为Company的数据
http://localhost:9200/elasticsearch/Company/_search

3.5 ElasticSearch所遇到过的问题

1 当查询的时候如果没有设置from和size,那么默认只会查出10条,不是我们想要的果

解决办法: 通过先查出总的条数,再将其值设置为size;

2 查询多条数据时遇到过的问题:

错误提示信息:Result window is too large
解决方案: 主要是修改index.max_result_window参数,默认为10000
命令:curl -XPUT http://127.0.0.1:9200/cmdb-now/_settings -d '{ "index" : { "max_result_window" : 100000000}}'

3 各种版本与api不匹配的问题

解决方式:上网找,以及测试api与版本

1.6 ElasticSearch架构及其支持的客户端连接方式

Es架构图

方式一:REST API ,端口 9200:这种连接方式对应于架构图中的RESTful style API这一层,这种客户端的连接方式是RESTful风格的,使用http的方式进行连接

方式二:Transport ,端口 9300:这种连接方式对应于架构图中的Transport这一层,这种客户端连接方式是直接连接ES的节点,使用TCP的方式进行连接;(ES7.0将会关闭Transport,8.0将完全删除,取而代之的是High Level REST Client)

ElasticSearch提供了两个JAVA REST client 版本:
Java Low Level REST Client: 低级别的REST客户端,通过http与集群交互,需自己编组请求JSON串,及解析响应JSON串。兼容所有ES版本。

Java High Level REST Client: 高级别的REST客户端,基于低级别的REST客户端,增加了编组请求JSON串、解析响应JSON串等相关api。使用的版本需要保持和ES服务端的版本一致,否则会有版本问题。

1.7 代码示例

    
    /**
     * @description: es工具类
     * @author: Guimu
     * @create: 2018/07/31 11:47:55
     **/
    @Component
    public class EsUtils {
        @Autowired
        private RestHighLevelClient client;
        private static final String CURRENT_MODEL_PACKAGE_NAME = "com.yy.elasticsearch.model.";
        private static final String DEFAULT_INDEX = "elasticsearch";
    
        /**
         * @Description: 根据Base 子类数据产生一个IndexRequest数据
         * @Param: [source]
         * @Return: org.elasticsearch.action.index.IndexRequest
         * @Author: Guimu
         * @Date: 2018/7/31  下午5:30
         */
        private IndexRequest indexRequestGenerater(Base source) {
            IndexRequest indexRequest = null;
            if (StringUtils.isEmpty(source.getIndex())) {
                source.setIndex(DEFAULT_INDEX);
            }
            try {
                String[] tempArr = source.getClass().getName().split("\\.");
                source.setType(tempArr[tempArr.length - 1]);
                indexRequest = new IndexRequest(source.getIndex(), source.getType());
                indexRequest.source(JacksonUtil.getString(source), XContentType.JSON);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return indexRequest;
        }
    
        /**
         * @Description: 批量存储接口, boolean  表示保存成功与否
         * @Param: [bases]
         * @Return: boolean
         * @Author: Guimu
         * @Date: 2018/7/31  下午5:32
         */
        public boolean batchSave(List<? extends Base> bases) {
            BulkRequest bulkRequest = new BulkRequest();
            bases.forEach(el -> bulkRequest.add(indexRequestGenerater(el)));
            boolean flag = false;
            try {
                BulkResponse bulkItemResponses = client.bulk(bulkRequest);
                flag = "created".equalsIgnoreCase(bulkItemResponses.getItems()[0].getResponse().getResult().name());
            } catch (IOException e) {
                e.printStackTrace();
            }
            return flag;
        }
    
        /**
         * @Description: 保存单个索引文档数据
         * @Param: [source]
         * @Return: boolean
         * @Author: Guimu
         * @Date: 2018/7/31  下午2:05
         */
        public boolean singleSave(Base source) {
            IndexRequest singleRequest;
            boolean flag = false;
            try {
                singleRequest = indexRequestGenerater(source);
                IndexResponse indexResponse = client.index(singleRequest);
                flag = "created".equalsIgnoreCase(indexResponse.getResult().name());
            } catch (IOException e) {
                e.printStackTrace();
            }
            return flag;
        }
    
        /**
         * @Description: 模糊匹配名字, 精确匹配corpId
         * @Param: [name, corpId]
         * @Return: java.util.List<com.yy.elasticsearch.model.Base>
         * @Author: Guimu
         * @Date: 2018/7/31  下午2:21
         */
        public List<Base> queryLikeNameAndCorpId(String name, String type, Long corpId) {
            MatchPhraseQueryBuilder mb1 = QueryBuilders.matchPhraseQuery("corpId", corpId);
            MatchPhraseQueryBuilder mb2 = QueryBuilders.matchPhraseQuery("name", "*" + name + "*");
            QueryBuilder queryBuilder = QueryBuilders.boolQuery().must(mb1).must(mb2);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            searchSourceBuilder.query(queryBuilder);
            SearchRequest searchRequest = new SearchRequest(DEFAULT_INDEX);
            searchRequest.types(type);
            searchRequest.source(searchSourceBuilder);
            return baseQuery(searchRequest);
        }
    
        /**
         * @Description: 查找指定corpId和type的所有数据
         * @Param: [name, corpId]
         * @Return: java.util.List<com.yy.elasticsearch.model.Base>
         * @Author: Guimu
         * @Date: 2018/7/31  下午2:21
         */
        public List<Base> queryByCorpId(String type, Long corpId) {
            MatchPhraseQueryBuilder mb = QueryBuilders.matchPhraseQuery("corpId", corpId);
            QueryBuilder queryBuilder = QueryBuilders.boolQuery().must(mb);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            searchSourceBuilder.query(queryBuilder);
            SearchRequest searchRequest = new SearchRequest(DEFAULT_INDEX);
            searchRequest.types(type);
            searchRequest.source(searchSourceBuilder);
            return baseQuery(searchRequest);
        }
    
        /**
         * @Description: 查询该索引中, 指定type的所有数据
         * @Param: [index, type]
         * @Return: java.util.List<com.yy.elasticsearch.model.Base>
         * @Author: Guimu
         * @Date: 2018/7/31  下午6:06
         */
        public List<Base> findAll(String index, String type) {
            SearchRequest searchRequest = new SearchRequest(index);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            searchSourceBuilder.from(0);
            searchSourceBuilder.size(this.getCount(searchRequest).intValue());
            searchRequest.source(searchSourceBuilder);
            //查询全部xxxxx
            searchRequest.types(type);
            return baseQuery(searchRequest);
        }
    
        /**
         * @Description: 获取该查询请求的总条数total
         * @Param: [searchRequest]
         * @Return: java.lang.Long
         * @Author: Guimu
         * @Date: 2018/7/31  下午4:58
         */
        private Long getCount(SearchRequest searchRequest) {
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            searchSourceBuilder.from(0);
            searchSourceBuilder.size(1);
            searchRequest.source(searchSourceBuilder);
            try {
                SearchResponse response = client.search(searchRequest);
                return response.getHits().getTotalHits();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return -1L;
        }
    
        /**
         * @Description: 私有的基础查询, 提高代码复用性
         * @Param: [searchRequest]
         * @Return: java.util.List<com.yy.elasticsearch.model.Base>
         * @Author: Guimu
         * @Date: 2018/7/31  下午6:15
         */
        private List<Base> baseQuery(SearchRequest searchRequest) {
            try {
                SearchResponse response = client.search(searchRequest);
                return Arrays.asList(response.getHits().getHits()).stream().map(el -> {
                    Map<String, Object> map = el.getSource();
                    Class clazz;
                    Base base = null;
                    try {
                        map.put("id", el.getId());
                        clazz = Class.forName(CURRENT_MODEL_PACKAGE_NAME + map.get("type").toString());
                        base = (Base) JacksonUtil.getObject(JacksonUtil.getString(map), clazz);
                    } catch (IOException | ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                    return base;
                }).collect(Collectors.toList());
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * @Description: 基础删除接口, 支持Base的所有子类
         * @Param: [base]
         * @Return: boolean
         * @Author: Guimu
         * @Date: 2018/7/31  下午6:32
         */
        public boolean deleteBase(Base base) {
            DeleteRequest deleteRequest = new DeleteRequest(base.getIndex(), base.getType(), base.getId());
            boolean flag = false;
            try {
                DeleteResponse deleteResponse = client.delete(deleteRequest);
                flag = "deleted".equalsIgnoreCase(deleteResponse.getResult().name());
                System.out.println(deleteResponse);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return flag;
        }
    
        /**
         * @Description: 此处传入的base的所有值都是全的,没有null值
         * @Param: [base]
         * @Return: boolean
         * @Author: Guimu
         * @Date: 2018/8/1  上午10:02
         */
        public boolean updateBase(Base base) {
            UpdateRequest updateRequest = new UpdateRequest(base.getIndex(), base.getType(), base.getId());
            boolean flag = false;
            try {
                updateRequest.doc(JacksonUtil.getString(base), XContentType.JSON);
                UpdateResponse updateResponse = client.update(updateRequest);
                flag = "updated".equalsIgnoreCase(updateResponse.getResult().name());
            } catch (IOException e) {
                e.printStackTrace();
            }
            return flag;
        }
    
        /**
         * @Description: 根据名字, type, corpId 进行精确查询Base数据,没找到则返回 null
         * @Param: [name, type, corpId]
         * @Return: com.yy.elasticsearch.model.Base
         * @Author: Guimu
         * @Date: 2018/8/1  上午9:35
         */
        public <T extends Base> T queryOneBase(String name, String type, Long corpId) {
            MatchPhraseQueryBuilder mb = QueryBuilders.matchPhraseQuery("corpId", corpId);
            MatchPhraseQueryBuilder mb1 = QueryBuilders.matchPhraseQuery("name", name);
            QueryBuilder queryBuilder = QueryBuilders.boolQuery().must(mb).must(mb1);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            searchSourceBuilder.query(queryBuilder);
            SearchRequest searchRequest = new SearchRequest(DEFAULT_INDEX);
            searchRequest.types(type);
            searchRequest.source(searchSourceBuilder);
            Base rebase = null;
            try {
                rebase = baseQuery(searchRequest).get(0);
            } catch (NullPointerException e) {
                e.printStackTrace();
            }
            Class<T> aClass = null;
            try {
                aClass = (Class<T>) Class.forName(CURRENT_MODEL_PACKAGE_NAME + type);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            return null == rebase ? null : aClass.cast(rebase);
        }
    
        public static String getDefaultIndex() {
            return DEFAULT_INDEX;
        }
    }
日记本
Web note ad 1