Table of Contents

1. 前览

Elasticsearch 7.*版本

Elasticsearch是什么

Elasticsearch是一个实时的分布式全文搜索引擎,可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。 Elasticsearch也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。

Elasticsearch历史

REST: 表现层状态转换(英语:Representational State Transfer,缩写:REST)是Roy Thomas Fielding 博士于2000年在他的博士论文中提出来的一种万维网软件架构风格,目的是便于不同软件/程序在网络(例如互联网)中互相传递信息,是风格而不是标准,只是提供了一组设计原则和约束条件。主要用于客户端和服务器交互类的软件。

RESTful API是符合REST设计风格的Web API,它从以下三个方面资源进行定义:

  • 直观简短的资源地址:URI,比如:http://example.com/resources
  • 传输的资源:Web服务接受与返回的互联网媒体类型,比如:JSON,XML,YAML等。
  • 对资源的操作:Web服务在该资源上所支持的一系列请求方法(比如:POST,GET,PUT或DELETE)
  • 创建过程

    Lucene是开源的、ES的前生

    1. Lucene只是一个库。想要使用它,你必须使用Java来作为开发语言并将其直接集成到你的应用中,更糟糕的是,Lucene非常复杂,你需要深入了解检索的相关知识来理解它是如何工作的。
    2. ES是基于Lucene,对其进行封装,通过简单的RESTful API来隐藏Lucene的复杂性,从而使得全文搜索变得简单。

    对比三家

    • Lucene是apache开放源代码的全文检索引擎工具包,是一个java信息检索程序库,但是比较复杂。

    • Elasticsearch实时的分布式搜索和分析引擎。全文搜索、结构化搜索、分析;

    • Solr同样也是基于Lucene的全文搜索服务器。

    • ES与Solr的选择:

      image-20210922125844606

      1. 单纯的对已有数据进行搜索时,Solr更快
      2. 当实时建立索引时,Solr会产生IO阻塞,查询性能较差,ES具有明显优势
      3. 随着数据量的增加,Solr的搜索效率会变得更低,而ES却没有明显的变化

2. Elasticsearch安装

下载安装

https://www.elastic.co/ 官网下载解压即可

我选择了7.12.1版本,与我项目的spring boot版本对应。解压即可。

image-20210923135849202

安装文件目录

image-20210923140631821

1
2
3
4
5
6
7
8
9
bin		启动文件
config	配置文件
	log4j2		日志配置文件
	elasticsearch.yml	elasticsearch 的配置文件! 集群、节点、端口
	jvm.options	java虚拟机相关配置
lib		相关jar包
logs	日志
modules	功能模块
plugins	插件!ik

启动ES,在命令行看到9200端口字样就说明已经启动了,可以访问该端口,会得到以下的结果。我的集群名字重新配置过,设置为了nowcoder,默认的情况下集群名是Elasticsearch。说明已经安装好了ES。

image-20210923141101777

3. Elasticsearch head安装使用

当作数据展示工具!所有的查询都用其他的来做比如:Kibana、postman

elasticsearch-head 是用于监控Elasticsearch状态的客户端插件,包括数据可视化、执行增删改查操作等。安装时需要先安装nodejs。

首先直接在https://github.com/mobz/elasticsearch-head上下载,按照文档进行操作。

在我的电脑上解压后得到如下图

image-20210923150031820

image-20210923150233967

按照上述进行操作。

  1. 进入elasticsearch-head

  2. npm install

    image-20210923150633762

  3. npm run statrt

    image-20210923150752884

    由于没有之前将ES关掉了,所以没有连接。重新开启ES,发现点击连接依然无法正常连接,打开浏览器控制台发现没有设置跨域连接。

    image-20210923151234927

    需要在elasticsearch.yml配置文件中增加两个配置项

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

    重新启动ES,可以看到已经正常连接了nowcoder

    image-20210923151818105

4. Kibana安装

Kibana可以将elasticsearch的数据的通过友好的页面展示出来,提供实时分析的功能。

安装很简单,不演示。

5. ES核心概念

elasticsearch是面向文档、关系型数据库和elasticsearch的对比。ES一切都是JSON!

Relational DB Elasticsearch
Database(数据库) Index
Table(表) Type(将要弃用)
Row(行) Document
Col(列) Field
  • Cluster 集群

    通用的集群概念。一个集群由一个唯一的名字标识,默认为“elasticsearch”。集群名称非常重要,具有相同集群名的节点才会组成一个集群。集群名称可以在配置文件中指定。

  • Node 节点

    形成集群的每个服务器称为节点。

  • Shard 分片

    当有大量的文档时,由于内存的限制、磁盘处理能力不足、无法足够快的响应客户端的请求等,一个节点可能不够。这种情况下,数据可以分为较小的分片。每个分片放到不同的服务器上。 当你查询的索引分布在多个分片上时,ES会把查询发送给每个相关的分片,并将结果组合在一起,而应用程序并不知道分片的存在。即:这个过程对用户来说是透明的。

  • Replication 副本、备份

    一个分片可以有多个备份(副本)

6. ES常用操作

image-20210922152950223

索引的操作

  • 创建

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    PUT /person
    {
      "settings": {
        "number_of_replicas": 1,
        "number_of_shards": 5
      }
    }
    
    PUT /person2/_doc/1
    {
      "name":"like",
      "age": 20,
      "time": "1993-02-12"
    }
    
  • 指定字段类型mapping

    https://www.elastic.co/guide/en/elasticsearch/reference/7.12/mapping-types.html

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    
    字符串类型string:
    	text:  一般被用于全文检索;  将当前Field进行分词
    	keyword:  当前Field不会被分词
    
    数值类型Numeric:
    	long;
        integer:
        short:
        byte:
        double:
        float:
        half_float:  精度比float小一半
        scaled_float:  根据一个long和scaled来表达一个浮点型, long-345,  scaled-100->3.45
    
    时间类型Date:
    	date: 针对时间类型指定具体的格式
    
    布尔类型:
    	boolean类型, 表达true和false
    
    二进制类型:
    	binary类型暂时支持Base64 encode string
    
    范围类型:
    	long_range:  赋值时,  无序指定具体的内容,  只需要存储一个范围即可, 指定gt, lt, gte, lte
    	integer_range:  同上
    	double_range:  同上
    	float_range:  同上
    	data_range:  同上
    	ip_range:   同上
    
    经纬度类型:
    	geo_point:  用来存储经纬度的
    
    ip类型
    	ip:  可以存储IPV4或IPV6
    
    
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    PUT /book
    {
      "mappings": {
        "properties": {
          "name":{
          "type":"text",
          "analyzer": "ik_max_word",
          "index":true,
          "store":false
        },
        "author": {
          "type":"keyword"
        },
        "count":{
          "type":"long"
        },
        "descr":{
          "type":"text",
          "analyzer":"ik_max_word"
        }
        }
      }
    }
    
    1. ik_max_word

      会将文本做最细粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为“中华人民共和国、中华人民、中华、华人、人民共和国、人民、共和国、大会堂、大会、会堂等词语。

    2. ik_smart

      会做最粗粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为中华人民共和国、人民大会堂。

  • 查看

    1
    
    GET /person3
    

    image-20210923161316577

  • 删除

    1
    
    DELETE /person
    

文档的基本操作

  • 新建文档

    1
    2
    3
    4
    5
    6
    7
    
    POST /book/_doc 
    {
      "name": "shuxue",
      "author": "zhangsan",
      "count": 5,
      "descr": "数学书"
    }
    

    会自动生成id,但是id号很奇怪,不推荐使用,使用POST也可以指定ID。使用PUT创建

    1
    2
    3
    4
    5
    6
    7
    
    PUT /book/_doc/1
    {
      "name": "yingyu",
      "author": "lisi",
      "count": 5,
      "descr": "英语书"
    }
    
  • 修改文档

    1
    2
    3
    4
    5
    6
    7
    8
    
    # 添加文档,  手动指定id为1, 覆盖式修改和这个一样
    PUT /book/_doc/4
    {
      "name": "yingyu已修改",
      "author": "lisi",
      "count": 4,
      "descr": "英语书"
    }
    

    使用覆盖操作会丢失数据

    image-20210923164645830

    1
    2
    3
    4
    5
    6
    
    POST /book/_update/4
    {
      "doc": {
        "count": 10
      }
    }
    

    image-20210923164918251

  • 删除文档

    1
    
    DELETE /book/_doc/2
    
  • 简单查询文档

    1
    2
    
    # 根据id来做简单查
    GET /book/_doc/1
    

7. 集成SpringBoot

主要要参看官方文档

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.12/java-rest-high-create-index.html

  1. 导入依赖(注意对应的版本)

    1
    2
    3
    4
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>
    
  2. 配置对象

    需要注入一个Bean

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    
    @Configuration
    public class ElasticSearchClientConfig {
    
        @Bean
        public RestHighLevelClient restHighLevelClient() {
            RestHighLevelClient client = new RestHighLevelClient(
                    RestClient.builder(
                            new HttpHost("localhost", 9200, "http")
                    )
            );
            return client;
        }
    }
    
  3. 测试

    编写测试类

    创建索引操作

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    
    public class ElasticsearchTest {
    
        @Autowired
        private RestHighLevelClient restHighLevelClient;
    
        @Test
        public void testCreateIndex() {
            CreateIndexRequest request = new CreateIndexRequest("test_index");
            try {
                CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
                System.out.println(createIndexResponse);
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    }