Elastic Search介绍及快速入门

434 阅读8分钟

一、初识ES及其下载安装

1.1 什么是ES

Elastic Search中文官网

Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎,同时是可扩展的数据存储和矢量数据库,能够应对日益增多的各种用例。作为 Elastic Stack 的核心,Elasticsearch 能够集中存储您的数据,实现闪电般的搜索速度、精细的相关性调整以及强大的分析能力,并且能够轻松地进行规模扩展。

简单的讲,ES就是为了实现如京东、淘宝、百度等网站的多关键词全文检索功能,用户输入多个关键词,ES可以根据关键词进行全文检索,展示给用户包含该关键词的所有搜索结果,提高用户体验。

image.png

1.2 下载与安装

Elasticsearch是由elastic公司开发的一套搜索引擎技术,它是elastic技术栈中的一部分。完整的技术栈包括:

  • Elastic Search:用于数据存储、计算和搜索
  • Logstash/Beats:用于数据收集
  • Kibana:用于数据可视化

其中Elastic Search与Kibana是我们主要使用的技术,接下来的下载与安装也主要介绍这两项技术,微服务中间件的使用大多布设于服务器,因此以下技术也基于Linux服务器介绍

前置环境要求
// 不同环境以及依赖版本可能会存在冲突,尽量保持版本一致
- JDK11
- Docker
- net网络环境(docker network create net)

1.2.1 Elastic Search下载与安装

  1. 首先需要拉取docker提供的ES与Kibana镜像或加载本地镜像
# 拉取远端ES
docker pull elasticsearch:7.12.1

# 加载本地ES
docker load -i elasticsearch.tar

1.2.2 Kibana下载与安装

Kibana是elastic公司提供的用于操作Elasticsearch的可视化控制台。它的功能非常强大,包括:

  • 对Elasticsearch数据的搜索、展示
  • 对Elasticsearch数据的统计、聚合,并形成图形化报表、图形
  • 对Elasticsearch的集群状态监控
  • 它还提供了一个开发控制台(DevTools),在其中对Elasticsearch的Restful的API接口提供了语法提示

为避免Kibana与ES产生冲突,要保证其与ES版本一致

# 拉取远端kibana
docker pull kibana:7.12.1

# 加载本地kibana
docker load -i kibana.tar
  1. 基于镜像创建容器并运行Elastic Search与Kibana

Kibana运行需要Elastic Search启动执行完毕,可以通过查看日志观察ES是否启动成功

运行ES:

docker run -d \
  --name es \
  -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
  -e "discovery.type=single-node" \
  -v es-data:/usr/share/elasticsearch/data \
  -v es-plugins:/usr/share/elasticsearch/plugins \
  --privileged \
  --network net \
  -p 9200:9200 \
  -p 9300:9300 \
  elasticsearch:7.12.1

查看日志:

docker logs -f es

运行Kibana:

docker run -d \
--name kibana \
-e ELASTICSEARCH_HOSTS=http://es:9200 \
--network=net \
-p 5601:5601  \
kibana:7.12.1

查看日志:

docker logs -f kibana
  • 安装完成后,直接访问5601端口,即可看到控制台页面:

image.png

  • 选择Explore on my own之后,进入主页面:

image.png

  • 然后选中Dev tools,进入开发工具页面:

image.png

1.3 倒排索引

Elastic Search之所以有如此高性能的搜索表现,正是得益于底层的倒排索引技术。

倒排索引的概念是基于MySQL这样的正向索引而言的。

假设有表:

IDtitleprice
1小米手机3499
2华为手机4999
3华为小米充电器49
4小米手环49
.........

基于MySQL(正排索引)而言,ID依然创建了索引,基于ID查询速度会很快,但是商品搜索用户输入的必然是title,此时就需要进行模糊匹配,当用户输入多个关键字,如非有商品包含所有关键字,且格式也与用户输入相同,查询SQL就会查询不到结果,显然不符合我们的预期。

倒排索引中有两个非常重要的概念:

  • 文档(Document):用来搜索的数据,其中的每一条数据就是一个文档。例如一个网页、一个商品信息
  • 词条(Term):对文档数据或用户搜索数据,利用某种算法分词,得到的具备含义的词语就是词条。例如:我是中国人,就可以分为:我、是、中国人、中国、国人这样的几个词条
词条(索引)文档id
小米1,3,4
手机1,2
华为2,3
充电器3
手环4

倒排索引就可以基于词条将文档分类,然后将词条与上述表格进行匹配,得到查询结果的ID列表,然后再基于ID区查询数据库得到最终数据。

正向索引与倒排索引有各自的优缺点:

正向索引

  • 优点:

    • 可以给多个字段创建索引
    • 根据索引字段搜索、排序速度非常快
  • 缺点:

    • 根据非索引字段,或者索引字段中的部分词条查找时,只能全表扫描。

倒排索引

  • 优点:

    • 根据词条搜索、模糊搜索时,速度非常快
  • 缺点:

    • 只能给词条创建索引,而不是字段
    • 无法根据字段做排序

ES官方提供的分词器会将中文的每一个字分为一个单独的词条,但是大多数情况下单独的字对用户来讲是没有意义的,所以我们需要引入中文分词器。

1.4 IK分词器

Elasticsearch的关键就是倒排索引,而倒排索引依赖于对文档内容的分词,而分词则需要高效、精准的分词算法,IK分词器就是这样一个中文分词算法。

  • 在线安装
docker exec -it es ./bin/elasticsearch-plugin  install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.12.1/elasticsearch-analysis-ik-7.12.1.zip

安装完成后需要重启ES: docker restart es

  • 离线安装
# 查看之前安装的ES的plugins数据卷目录
docker volume inspect es-plugins

# 得到Mountpoint这个属性对应的值就是挂载目录,将本地ik文件上传至本目录下
# 重启ES
docker restart es

IK分词器包含两种模式:

  • ik_smart:智能语义切分
  • ik_max_word:最细粒度切分

二、索引库操作

Index就类似数据库表,Mapping映射就类似表的结构。我们要向es中存储数据,必须先创建Index和Mapping

2.1 Mapping映射属性

Mapping是对索引库中文档的约束,常见的Mapping属性包括:

  • type:字段数据类型,常见的简单类型有:

    • 字符串:text(可分词的文本)、keyword(精确值,例如:品牌、国家、ip地址)
    • 数值:longintegershortbytedoublefloat
    • 布尔:boolean
    • 日期:date
    • 对象:object
  • index:是否创建索引,默认为true

  • analyzer:使用哪种分词器

  • properties:该字段的子字段

2.2 索引库的CRUD

由于Elasticsearch采用的是Restful风格的API,因此其请求方式和路径相对都比较规范,而且请求参数也都采用JSON风格。

我们直接基于Kibana的DevTools来编写请求做测试,由于有语法提示,会非常方便。

2.2.1 创建索引库和映射

基本语法

  • 请求方式:PUT
  • 请求路径:/索引库名,可以自定义
  • 请求参数:mapping映射
PUT /索引库名称
{
  "mappings": {
    "properties": {
      "字段名":{
        "type": "text",
        "analyzer": "ik_smart"
      },
      "字段名2":{
        "type": "keyword",
        "index": "false"
      },
      "字段名3":{
        "properties": {
          "子字段": {
            "type": "keyword"
          }
        }
      },
      // ...略
    }
  }
}

2.2.2 查询索引库

基本语法

  • 请求方式:GET
  • 请求路径:/索引库名
  • 请求参数:无
GET /索引库名

2.2.3.修改索引库

倒排索引结构虽然不复杂,但是一旦数据结构改变(比如改变了分词器),就需要重新创建倒排索引,这简直是灾难。因此索引库一旦创建,无法修改mapping

虽然无法修改mapping中已有的字段,但是却允许添加新的字段到mapping中,因为不会对倒排索引产生影响。因此修改索引库能做的就是向索引库中添加新字段,或者更新索引库的基础属性。

PUT /索引库名/_mapping
{
  "properties": {
    "新字段名":{
      "type": "integer"
    }
  }
}

2.2.4 删除索引库

语法:

  • 请求方式:DELETE
  • 请求路径:/索引库名
  • 请求参数:无
DELETE /索引库名

三、项目整合ES

3.1 导入依赖

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>

3.2 覆盖Spring Boot的默认ES版本

<properties> 
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <elasticsearch.version>7.12.1</elasticsearch.version> 
</properties>

3.3 创建配置类将Client注册为Bean

@Configuration
public class ElasticSearchConfig {

    /**
     * es集群地址
     */
    private static final String HOST = "http://服务器IP:9200";

    /**
     * 创建客户端
     * @return RestHighLevelClient
     */
    @Bean
    public RestHighLevelClient restHighLevelClient() {
        return new RestHighLevelClient(RestClient.builder(
                HttpHost.create(HOST)
        ));
    }
}

至此集成已经完成,已经可以开始测试使用了

四、MySQL与ES概念的对比

我们统一的把mysql与elasticsearch的概念做一下对比:

MySQLElasticsearch说明
TableIndex索引(index),就是文档的集合,类似数据库的表(table)
RowDocument文档(Document),就是一条条的数据,类似数据库中的行(Row),文档都是JSON格式
ColumnField字段(Field),就是JSON文档中的字段,类似数据库中的列(Column)
SchemaMappingMapping(映射)是索引中文档的约束,例如字段类型约束。类似数据库的表结构(Schema)
SQLDSLDSL是elasticsearch提供的JSON风格的请求语句,用来操作elasticsearch,实现CRUD

是不是说,我们学习了elasticsearch就不再需要mysql了呢?

并不是如此,两者各自有自己的擅长之处:

  • Mysql:擅长事务类型操作,可以确保数据的安全和一致性

  • Elastic Search:擅长海量数据的搜索、分析、计算

因此在企业中,往往是两者结合使用:

  • 对安全性要求较高的写操作,使用MySQL实现

  • 对查询性能要求较高的搜索需求,使用Elastic Search实现

  • 两者再基于某种方式,实现数据的同步,保证一致性