SpringBoot集成ElasticSearch

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;
        }
    }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 197,814评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,124评论 2 375
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 144,814评论 0 327
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,924评论 1 268
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,815评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,562评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,944评论 3 388
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,582评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,859评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,881评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,700评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,493评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,943评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,115评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,413评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,978评论 2 343
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,182评论 2 339

推荐阅读更多精彩内容

  • 基础概念 Elasticsearch有几个核心概念,从一开始理解这些概念会对整个学习过程有莫大的帮助。 接近实时(...
    山天大畜阅读 2,100评论 0 4
  • 一、环境搭建 软件版本: Linux:centos7 64bit JDK:1.8.0 elasticsearch:...
    lailai900201阅读 3,561评论 0 12
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,528评论 18 139
  • 简介 Elasticsearch是一个高可扩展的开源全文搜索和分析引擎,它允许存储、搜索和分析大量的数据,并且这个...
    零度沸腾_yjz阅读 5,519评论 0 8
  • 离开九天之后,昨天晚上返回杭州。这段时间万伊若发生了很大变化,她依然认得我,一进门就对着我呵呵地笑。 万伊若已经会...
    wanjunping阅读 236评论 0 0