ElasticSearch入门详解(结合Kibana)

前言

ElasticSearch是基于java的开源分布式搜索引擎,由于其强大的检索性能和较好的封装性(对lunece),给用户提供了简单易上手的API操作,也成为当前各大企业和大厂用于搜索引擎的工具。本文将对ElasticSearch的使用和入门进行详细的讲解,并结合Kibana进行部分案例的演示,希望可以让各位读者有所收获。想要获取更多有关ElasticStack其他成员的使用,可以关注本文集的其他文章。

一、应用安装

(一)安装ElasticSearch

1. 去官网下载解压包:https://www.elastic.co/downloads/elasticsearch


2. 解压和使用
将压缩包解压到指定路径后,进入bin目录执行elasticsearch.bat即可启动

注意:

  • ElasticSearch依赖于jdk环境,要求本地的jdk版本最低为jdk1.8!
  • ElasticSearch官网可能进不去,有需要的话可以从文章中获取百度网盘链接

(二)安装Kibana

  • 进入官网下载:https://www.elastic.co/cn/kibana
  • 解压和使用
    将压缩包解压后,进入bin目录执行kibana.bat即可

    如果对应的elasticsearch服务不在默认的端口和ip,则需要进入到config目录中,在kibana.yml文件中添加对应的配置
    elasticsearch.hosts: ["http://localhost:9200"]
    # 要修改启动kibana的端口的话,可以修改下面的配置
    server.port: 5601
    

    (三)安装elasticsearch-head插件

    elasticsearch-head将是一款专门针对于elasticsearch的客户端工具,我们可以通过这个可视化工具来便捷地查看当前es集群的各种信息。

    1. 下载地址:https://github.com/mobz/elasticsearch-head
    2. 解压和安装
      elasticsearch-head依赖于node.js,我们需要提前准备好相关的环境,解压后进入主目录执行下面的命令
    # 下载对应前端依赖 (如果太慢的话可以换成淘宝镜像下载,具体自行百度)
    npm install 
    # 启动
    npm run start
    

    由于跨域问题的存在,使用elasticsearch-head前我们需要先进入前面安装elasticsearch的目录中配置允许跨域


    添加入下配置:

    http.cors.enabled: true
    http.cors.allow-origin: "*"
    

    二、ES的核心概念

    (一)数据类型

    elasticsearch是面向文档关系行数据库,为了便于理解其相关的核心概念,我们可以将其与传统的关系型数据库进行参考,以便快速的理解核心概念的含义。

    名称 含义
    数据库(database) 索引(indices)
    表(tables) types (慢慢被弃用)
    行(rows) documents
    字段(columns) fields

    (二)检索方式——倒排索引

    以下图为例,左侧是文章id和每篇文章对应的标签。当使用倒排索引的时候,会将标签分为两类,这样的话当我们想搜索和python相关的博客的时候,就无需搜索全部文章,而只需要从索引列表中检索即可。大大提高了检索效率。(倒排索引的核心在于分词)

    三、实操——通过REST风格进行ES的CRUD操作

    method url地址 描述
    PUT localhost:9200/索引名称/类型名称/文档id 创建文档(指定文档id)
    POST localhost:9200/索引名称/类型名称 创建文档(随机文档id)
    POST localhost:9200/索引名称/类型名称/文档id/_update 修改文档
    DELETE localhost:9200/索引名称/类型名称/文档id 删除文档
    GET localhost:9200/索引名称/类型名称/文档id 通过文档id查询文档
    POST localhost:9200/索引名称/类型名称/_search 查询所有的数据

    启动ESKibana服务,进入Kibana左侧菜单栏的Dev Tool

    (一)PUT 命令

    1、使用es默认提供的数据类型

    PUT /index_test1/_doc/1
    {
      "name": "小明",
      "age": 10
    }
    

    响应结果

    {
      "_index" : "index_test1",
      "_type" : "_doc",
      "_id" : "1",
      "_version" : 1,
      "result" : "created",
      "_shards" : {
        "total" : 2,
        "successful" : 1,
        "failed" : 0
      },
      "_seq_no" : 0,
      "_primary_term" : 1
    }
    

    我们可以看到,通过这种方式新建的索引数据,es会默认给上对应的字段类型。如果有需要指定类型的话,需要我们进行自定义。

    2、自定义索引表字段类型
    2.1、字段的类型

    字符串类型: text、keyword
    数值类型: long、integer、short、byte、double、float、half、float、scaled、
    日期类型:date
    布尔值类型: boolean
    二进制类型: binary

    2.2、自定义索引字段类型
    PUT /index_test2
    {
      "mappings": {
        "properties": {
          "name": {
            "type": "text"
          },
          "age": {
            "type": "integer"
          }
        }
      }
    }
    

    我们可以看到自定义字段后,再次查询得到的结果就是我们定义好的类型了。


    2.3、扩展命令
    GET _cat/health    获取es健康值
    GET _cat/indices       获取es的所有索引
    
    2.4、索引数据修改
    • 使用PUT命令
    PUT /index_test1/_doc/1
    {
      "name": "小蓝"
    }
    

    响应结果如下:

    {
      "_index" : "index_test1",  // 索引名称
      "_type" : "_doc",  // 索引类型
      "_id" : "1",   // 数据id
      "_version" : 2, // 版本,每修改一次数据版本+1
      "result" : "updated",  // 状态:已更新
      "_shards" : {
        "total" : 2,
        "successful" : 1,
        "failed" : 0
      },
      "_seq_no" : 1,
      "_primary_term" : 1
    }
    

    我们查看数据发现,源数据确认已经修改成功,但是age字段的值却变为了空。


    这是因为elasticSearch使用PUT命令进行更新的时候,对于没有赋值的字段会一律修改为空。所以一般来说,我们基本上是使用POST方法来进行更新的

    POST /index_test1/_doc/1/_update
    {
      "doc": {
        "name": "小蓝"
      }
    }
    

    (二)DELETE

    DELETE一般用于索引的删除,使用方式也十分简单

    DELETE /index_test1
    

    (三)GET

    我们可以利用GET来查看索引和文档,查询的请求头格式如下:

    GET /索引/类型/文档
    

    对于查询体,也就是查询的具体条件,es支持两种查询方式。常规的REST URI方式和REST 请求体方式

    URI方式



    对于REST请求体方式,则在下一节进行讲解

    四、关于ES多条件查询详解

    1. 模糊查询(match)
    GET /index_test1/_doc/_search
    {
      "query": {
        "match": {
          "name": "小明"
        }
      }
    }
    
    2. 排序(sort)
    GET /index_test1/_doc/_search
    {
      "query": {
        "match": {
          "name": "小明"
        }
      },
      "sort": [
        {
          "age": "desc"
        }
      ]
    }
    
    3. 字段选择(source)
    GET /index_test1/_doc/_search
    {
      "query": {
        "match": {
          "name": "小明"
        }
      },
      "_source": ["name"]
    }
    
    4. 限制结果记录条数(from 、size)
    GET /index_test1/_doc/_search
    {
      "query": {
        "match": {
          "name": "小明"
        }
      },
      "from": 1, 
      "size": 1 
    }
    
    5. 条件查询(可以写多个查询条件,并进行与或非逻辑判断)
    GET /index_test1/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "name": "小明"
              }
            },
            {
              "match": {
                "age": 11
              }
            }
          ]
        }
      }
    }
    
    6. 过滤器(filter)
    - gt  大于
    - gte 大于或等于
    - lt  小于
    - lte 小于或等于
    
    GET /index_test1/_search
    {
      "query": {
        "bool": {
          "must_not": [
            {
              "match": {
                "name": "明"
              }
            }
          ],
          "filter": {
            "range": {
              "age": {
                "gte": 15,
                "lte": 26
              }
            }
          }
        }
      }
    }
    
    7. 精准查询(term)

    term 查询是直接通过倒排索引指定的词条进行精确查找的,因为倒排索引大大缩小了检索的范围,这也使得使用term关键字的搜索效率很高。

    GET /index_test1/_search
    {
      "query": {
        "term": {
          "name": "明"
        }
      }
    }
    
    8. 高亮查询
    GET /index_test1/_search
    {
      "query": {
        "match": {
          "name": "小明"
        }
      },
      "highlight": {
        "pre_tags": "<p class='a' >",
        "post_tags": "</p>", 
        "fields": {
          "name": {}
        }
      }
    }
    

    五、在项目(JAVA)中使用ES客户端进行操作

    (一)新建项目并导入项目依赖

    创建一个springboot的项目 同时勾选上springboot-web的包以及Nosql的elasticsearch的包

    <dependency>
         <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
      </dependency>
      <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
     </dependency>
    

    注意,引入后要注意ElasticSearch的客户端的版本是否和本地的es版本一致


    如果不一致的话,就手动配置

        <properties>
            <!-- 这里的话,要和自己本地的es版本保持一致 -->
            <elasticsearch.version>7.6.1</elasticsearch.version>
        </properties>
    

    (二)注入RestHighLevelClient 客户端

    @Configuration
    public class ElasticSearchConfig {
    
        @Bean
        public RestHighLevelClient restHighLevelClient(){
            RestHighLevelClient restHighLevelClient = new RestHighLevelClient(
                    RestClient.builder(new HttpHost("localhost",9200,"http"))
            );
            return restHighLevelClient;
        }
    }
    

    (三)使用客户端操作索引数据

    1. 创建索引
        // 测试创建索引
        @Test
        void createESIndext() throws IOException {
            // 创建索引请求
            CreateIndexRequest request = new CreateIndexRequest("xiaoming_index");
            // 通过高级客户端调用相关索引客户端,并执行请求
            CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
            // 输出请求
            System.out.println(createIndexResponse);
        }
    
    2. 查询索引是否存在
    // 测试查询索引
        @Test
        void searchESIndext() throws IOException {
            // 创建索引请求
            GetIndexRequest request = new GetIndexRequest("xiaoming_index");
            // 通过高级客户端调用相关索引客户端,并执行请求
            boolean isExist = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
            // 输出请求
            System.out.println("xiaoming_index is Exist : " + isExist);
        }
    
    3.删除索引
     // 测试删除索引
        @Test
        void deleteESIndext() throws IOException {
            // 创建索引请求
            DeleteIndexRequest request = new DeleteIndexRequest("xiaoming_index");
            // 通过高级客户端调用相关索引客户端,并执行请求
            AcknowledgedResponse response = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
            // 输出请求
            System.out.println(response.isAcknowledged());
        }
    
    4. 创建索引文档
    // 测试创建文档
        @Test
        void createESDocument() throws IOException {
            // 创建对象
            Student stu = new Student("小明",18);
            // 创建索引相关请求
            IndexRequest request = new IndexRequest("xiaoming_index");
            // 配置请求相关参数
            request.id("1");
            request.timeout("1s");
            request.source(JSON.toJSONString(stu), XContentType.JSON);
            // 通过客户端执行请求
            IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
            // 输出请求
            System.out.println(response.status());
        }
    
    5. 判断文档是否存在
     // 判断文档是否存在
        @Test
        void searchESDocument() throws IOException {
            // 创建索引相关请求
            GetRequest request = new GetRequest("xiaoming_index", "1");
            // 配置不显示索引上下文
            request.fetchSourceContext(new FetchSourceContext(false));
            request.storedFields("_none_");
            // 获取文档信息
            boolean exists = restHighLevelClient.exists(request, RequestOptions.DEFAULT);
            // 输出请求
            System.out.println(exists);
        }
    
    6. 获取文档内容
    @Test
        void searchESDocumentDetails() throws IOException {
            // 创建索引相关请求
            GetRequest request = new GetRequest("xiaoming_index", "1");
            // 获取文档信息
            GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT);
            // 输出具体数据
            System.out.println(response.getSourceAsString());
            // 输出全部结果
            System.out.println(response);
        }
    
    7. 更新文档内容
     @Test
        void updateESDocumentDetails() throws IOException {
            // 创建索引相关请求
            UpdateRequest request = new UpdateRequest("xiaoming_index", "1");
            // 插入更新的文档内容
            Student student = new Student("大明", 14);
            request.doc(JSON.toJSONString(student),XContentType.JSON);
            // 更新文档信息
            UpdateResponse response = restHighLevelClient.update(request, RequestOptions.DEFAULT);
            // 输出具体数据
            System.out.println(response.status());
            // 输出全部结果
            System.out.println(response);
        }
    
    8. 删除文档记录
    // 删除文档记录
        @Test
        void deleteESDocumentDetails() throws IOException {
            // 创建索引相关请求
            DeleteRequest request = new DeleteRequest("xiaoming_index", "1");
            // 更新文档信息
            DeleteResponse response = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
            // 输出具体数据
            System.out.println(response.status());
            // 输出全部结果
            System.out.println(response);
        }
    
    9. 对文档记录进行批量操作
     @Test
        void bulkESDocument() throws IOException {
            // 创建批量操作索引请求
            BulkRequest bulkRequest = new BulkRequest();
            // 初始化数据
            ArrayList list = new ArrayList();
            list.add(new Student("小红", 15));
            list.add(new Student("小蓝", 15));
            list.add(new Student("小黑", 63));
            list.add(new Student("小青", 14));
            // 创建具体的插入数据请求,并加入到批量请求中
            for(int i = 0 ;i<list.size() ; i++){
                bulkRequest.add(new IndexRequest("xiaoming_index")
                .id(String.valueOf(i+1))
                .source(JSON.toJSONString(list.get(i)),XContentType.JSON));
            }
            // 执行批量操作
            BulkResponse response = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
            // 输出具体数据
            System.out.println(response.status());
            // 输出全部结果
            System.out.println(response);
        }
    
    10.根据条件查询文档信息
     @Test
        void searchDocumentByCondition() throws IOException {
            // 创建请求对象
            SearchRequest searchRequest = new SearchRequest("xiaoming_index");
            // 创建查询条件
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            searchSourceBuilder.query(QueryBuilders.matchQuery("name", "蓝"));
            searchRequest.source(searchSourceBuilder);
            // 执行查询
            SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            System.out.println(JSON.toJSONString(response.getHits()));
            for (SearchHit hit : response.getHits().getHits()) {
                System.out.println(hit.getSourceAsMap());
            }
        }
    

    参考学习视频:
    【狂神说Java】ElasticSearch7.6.x最新完整教程通俗易懂
    https://www.bilibili.com/video/BV17a4y1x7zq(一个蛮好的up主,大家可以多关注关注)

    posted @   moutory  阅读(78)  评论(0编辑  收藏  举报  
    相关博文:
    阅读排行:
    · 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
    · 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
    · 【自荐】一款简洁、开源的在线白板工具 Drawnix
    · 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
    · Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
    点击右上角即可分享
    微信分享提示