ZhuangRenyang / blog

蝉时雨网站文章仓库
https://ovoz.cn
3 stars 0 forks source link

ElasticSearch全文搜索引擎 #50

Open ZhuangRenyang opened 1 year ago

ZhuangRenyang commented 1 year ago

ElasticSearch

ElasticSearch简称ES,但是在查找资料时需要输入全称,才能得到高价值的结果

ES是全文搜索引擎,是从数据库中获取数据,根据数据生成索引,把索引数据保存到ES中,也是可以保存数据

之后查询,是从ES中进行查询。但是和redis和mysql不一样,不仅服务于java语言,其他语言也是可以使用的

ES是一个软件,可以直接启动,那么需要同学们下载好软件

ES的底层技术

ES使用的Doug Cutting利用java语言根据倒排索引的理念开发的一套名为Lucene的API

为什么需要ElasticSearch

数据库进行模糊查询效率严重低下,所有关系型数据库都有这个缺点,在执行类似以下的模糊查询时:

select * from spu where spu_name like '%手机%'

经过测试证明一张千万级别的数据表进行模糊查询需要20秒以上

当前互联网项目要求“三高”的需求下,这样的效率肯定不能接收

ES主要是为了解决数据库模块查询性能低下的问题的

ES经过优化之后,从同样数据量的ES中查询相同条件数据,效率能够提供100倍以上

数据库索引

所谓索引(index)其实就是数据目录

通常情况下,索引是为了提高查询效率的

数据库索引通常情况下分为两类:聚集索引、非聚集索引

聚集索引就是数据库保存数据的物理顺序,默认情况下就是主键id,所以按id查询数据库中的效率非常高

如果想在非主键列上添加索引,就是非聚集索引

例如:在创建索引时,在表中的name这一列创建

然后我们在搜索时,如果按name索引进行查询,查询效率比较高,如果没有索引,查询时是一行一行的查询,效率低下

模糊查询时因为'%手机%',使用的是前模糊查询,使用索引必须明确前面的内容是什么,前模糊查询是不能使用索引的,只能全表的逐行搜索,所以效率低

索引面试题

  1. 创建的索引会占用硬盘空间
  2. 创建索引之后,对该表进行增删改操作时,会引起索引的更新,所以效率会降低
  3. 对数据库进行批量新增时,先删除索引,增加完毕之后再创建
  4. 不要对数据样本少的列添加索引
  5. 每次从数据库表中查询的数据的比例越高,索引的效果越差
  6. 当我们执行查询时,where条件后应该先查询有索引的列

ES的运行原理

ES软件再保存数据时,和关系型数据库不一样

在将数据保存到ES时,可以对指定的列进行分词索引保存,保存在索引库中,形成倒排索引结构,这个时候就可以根据关键字搜索内容

image-20230106201344198

ES的安装和启动

解压ES的安装包到没有中文和空格的路径中即可

image-20230106201942695

找到bin目录下的elasticsearch.bat,双击启动即可

启动之后访问:localhost:9200

image-20230106202204006

ES基本使用

ES启动完成后,我们学习如何使用ES

我们从创建一个ES的项目:elasticsearch,在项目中使用ES

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>cn.tedu</groupId>
        <artifactId>csmall</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>cn.tedu</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>elasticsearch</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

创建能够向ES发送请求的文件,文件类型:HTTP Request类型,是http client文件,可以指定url发送请求的格式

我们从最简单的请求开始

GET http://localhost:9200

### 三个#既是分隔符也是注释,两个请求之间必须使用它来分割,否则无法运行
POST http://localhost:9200/_analyze
Content-Type: application/json

{
  "text": "I am LiHua",
  "analyzer": "standard"
}

analyze:分析

analyzer:分析者(分词器)

​ "analyzer": "standard" 是可以省略的

standard这个分词器只能对英文生效(有空格的),但是中文分词不能按空格分割。如果按照这个分词器切分,我们就会发现,切分成一个个的字,显示是不满足我们日常的搜索需求

我们要解决中文分词的问题,需要用到IK分词器,这个一个中文常见词语的词库,分词时按照词库的单词进行分词

解压ik分词器的压缩包,有以下内容,复制所有内容

image-20230106210804899

自己在ES软件的plugins文件夹下创建一个叫ik的子文件夹,把上面的内容,粘贴过来

image-20230106211023825

安装完ik插件之后,需要重启ES才能生效

POST http://localhost:9200/_analyze
Content-Type: application/json

{
  "text": "罗技主宰者有线游戏鼠标",
  "analyzer": "ik_smart"
}

再次测试运行,可以看到正常的中文分词效果

IK分词插件的使用

我们安装的ik实际上不只一个分词器

实际上除了ik_smart之外还有ik_max_word

POST http://localhost:9200/_analyze
Content-Type: application/json

{
  "text": "罗技主宰者有线游戏鼠标",
  "analyzer": "ik_smart"
}
### 三个#既是分隔符也是注释,两个请求之间必须使用它来分割,否则无法运行
POST http://localhost:9200/_analyze
Content-Type: application/json

{
  "text": "罗技主宰者有线游戏鼠标",
  "analyzer": "ik_max_word"
}

上面两个分词器运行分词结果会有非常明显的区别

区别总结如下:

​ 优点:特征是粗略快速的将文字进行分词,占用空间小,查询速度快

​ 缺点:分词的颗粒度大,可能会跳过一些重要分词,导致查询结果不全面,查全率低

​ 优点:特征是详细的文字片段进行分词,查询时查全率高,不容易遗落数据

​ 缺点:因为分词太过详细,导致有一些无用分词,占用空间,查询速度慢

使用ES操作数据

ES是一个数据库性质的软件

可以执行增删改查操作,但是操作时也需要类似分库分表的形式取操作不同的数据

我们先了解一下ES保存数据的结构

image-20230106213131450

ES启动后,ES服务可以创建多个index(索引),index可以理解成数据库中的表的概念

一个index可以创建多个保存数据的document(文档)

一个document理解为数据库表中的一行数据

一个document中可以保存多个属性和属性值,对应数据库表中的字段和字段值