谷粒商城-全文检索-ElasticSearch

1.简介

一个分布式的开源搜索和分析引擎,可以 秒 级的从海量数据中检索

主要功能:做数据的检索和分析(MySQL专攻于数据的持久化存储与管理CRUD达到百万以上的数据MSQL就会很慢,海量数据的检索和分析还是要用ElasticSearch)

用途:我们电商项目里的所有的检索功能都是由ElasticSearch完成的

底层:开源库 Lucene ,然后对 Lucene 进行封装,提供了 REST API 接口,开箱即用

REST API: 天然的跨平台

版本对应:

1.基本概念

类比MySQL:

1.Index(索引)

1.动词:类似于MySQL的insert: 创建一条数据在 ElasticSearch 里叫 索引一条数据

2.名词:类似于MySQL的Database

2.Type(类型) (es7以后不能再创建多个type,只能用默认的,已被弃用)

在 Index 中可以定义一个或者多个 Type

类似于MySQL 数据库 和 表 的关系:MySQL里叫在某个数据库的某张表里,在ES里叫某个索引的某个类型下

已经没有type了 现在索引就是表 索引还有映射  然后索引库里边存的就是文档了.......

3.Document(文档)

保存在某个索引(Index)下,某种类型(Type)的一个数据(Document),文档是JSON格式的,Document就像是 MySQL中的某个Table 里面的内容;

4.倒排索引

比如我们保存一条记录:红海行动

ES会先把 红海行动 进行分词,比如分成 红海 和 行动 两个单词,除了存入1号记录 红海行动 这个文档之外,额外又维护了一张 倒排索引表 :倒排索引表就会存 红海 1,行动 1,两个文档

然后我们再来保存2号记录 探索红海行动

先分词成: 探索 红海 行动 ,先存入2号记录 探索红海行动 ,再额外维护 倒排索引表 更新 红海 和 行动的记录 加入 探索 的记录 :红海 1,2 和 行动 1,2 和 探索 2 

以此类推....

然后当我们检索时 输入 红海特工行动 它也会分词成为 红海 特工 行动 三个单词,然后会从倒排索引表里找到 红海 特工 行动  这三个词的记录 就会查到 12345条记录,但是哪一个才是更贴和我们的搜索目标呢,引入一个相关性得分(比如3号记录共有3个单词命中了两个,相关性得分2/3),我们就会根据相关性得分从高到低排序

2.Docker安装(国内镜像已经停用了,解决谷粒商城docker pull的问题)

替换视频中的docker镜像,直接装在centOS7上

在CentOS 7上安装和配置Elasticsearch的方法_centos7搭建elasticsearch-****博客

然后要在elasticsearch.yml上添加这个配置: http.host: 0.0.0.0

然后安装kibana:

参考这个博主:

CentOS 7 上安装 Kibana 7.12.1_kibana 7.12.1 license-****博客

做完这两个博主的内容就能跳过视频P104

3.初步检索

因为封装成 REST API,我们直接使用APIfox发请求就能用

1._cat

GET/_cat/nodes:查看所有节点


GET/_cat/health:查看 es 健康状况


GET/_cat/master:查看主节点


GET/ cat/indices:查看所有索引 相当于MySQL里的show databases;

2.索引一个文档(保存)

因为ES8以后不能创建多个type所以我们用到的请求是

emmmES7应该只是化了type的概念,跟着视频里应该也可以,因为我们这里装的是7.9.2的ES

我建议还是使用post发/_doc吧,以后会慢慢更新淘汰掉视频里的语法的

视频中的方法:

POST:

3.查询文档(乐观锁)

乐观锁,当他们并发发送请求的时候,可以加上判断条件if_seq_no=3,当seq_no=3时才能操作成功,且成功后seq_no会改变,当另一条请求也带上判断条件if_seq_no=3时,操作就会失败

模拟并发更改:

同时对id为1的数据发送put请求更改name:

当第一条请求带上乐观锁操作发出去且seq_no=3时

此时再发送第二条请求也带上乐观锁操作让seq_no=3时:

4.更新文档

POST:

当带了_update 语法一定要带上 doc

_update会对比原数据,如果本次传的数据和原数据一模一样,版本号就不会加,操作就是noop(没有操作),序列号(_seq_no)也不变

不带_update 语法不加 doc://等同于PUT不加_update

不会检测原数据直接更新,版本号,序列号都会加

5.删除文档

6.bulk批量API

必须发POST请求

来到Kiana

批量保存测试数据:

es测试数据.json · 坐看云起时/common_content - Gitee.com

4.进阶检索

1.SearchAPI

ES 支持两种基本方式检索

        一个是通过使用 REST request URl 发送搜索参数(uri+检索参数)

        另一个是通过使用 REST requestbody 来发送它们(uri+请求体)

2.Query DSL(查询领域对象语言)上面第二种方法的请求体

1.基本语法格式

2.只返回部分字段

"_source":["name","age"],只返回name和age字段

3.match匹配查询

match,条件查询指定的是一个非字符串的属性,就是精确查询

当指定的是字符串的属性就是模糊查询:(全文检索)(倒排索引),最终会按照评分去进行排序,会对检索的字符串进行分词

4.match_phrase(短语匹配)

对字符串不进行分词(精确查询)

5.multi_match(多字段匹配)

6.bool(复合查询)

must:必须满足,

must_not:必须不满足

should:应该,满足最好,不满足也行(满足了加评分,会排在前面)

7.filter(结果过滤)

不会贡献文档的相关性得分

不用filter:

用了filter

8.term

类似于match,term用来找精确值字段,例如age

match用来全文检索,字符串模糊查询用,例如address

文本用match,数字用term

另外,区别 match_phrase 和 属性名.keyword :

9.aggregations(执行聚合)

分析和检索是一次性的:一次请求过去,我们既能查出数据,也能把数据分析到位

例如需求是:搜索 address 中包含 mill 的所有人的年龄分布以及平均年龄,但不显示这些人的详情。

先看看查出所有 address 中包含 mill 的所有人, 并列举出他们的年龄分布

再加一个平均值聚合

如何不看这些人的详细信息呢,我们让size=0,就可以只看聚合结果:

进阶:子聚合 按照年龄聚合,并且请求这些年龄段的这些人的平均薪资

就可以查到如下结果:

再进阶:查出所有年龄分布,并且这些年龄段中M(男)的平均薪资和F(女)的平均薪资以及这个年龄
段的总体平均薪资

3.Mapping映射

定义一个文档如何被进行处理的:例如我们可以定义那个string类型的字段是可以被当作全文检索的

像是创建SQL表时定义每一列数据类型是什么

1.字段类型

ES会在第一次保存数据的时候自动猜测数据类型

2.映射

就是每一个文档的数据类型是什么

我们可以查看mapping信息

我们也可以在创建索引时指定映射(有很多类型,可以参考文档)

1.修改映射

1.添加新的字段映射:

2.修改已经存在的字段

对于已经存在的映射字段,我我们是不能更新的

3.数据迁移

因为映射不支持修改,我们想要修改,能用的办法就是新建一个映射字段,把数据迁移进去:

先创建一个新索引

下一步数据迁移:

这是没有type的写法

4.分词

一个  tokenizer(分词器)  接收一个字符流,将之分割为独立的 tokens(词元,通常是独立的单词),然后输出 tokens 流。例如,whitespace tokenizer遇到空白字符时分割文本。它会将文本"Quick brown fox!"分割为 [Quick, brown, fox!]。
该 tokenizer(分词器)  还负责记录各个term(词条) 的顺序或 position 位置(用于 phrase 短语和 word proximity词近邻查询),以及 term(词条)所代表的原始word(单词)的 start(起始)和 end(结束)的 characteroffsets(字符偏移量)(用于高亮显示搜索的内容)。

Elasticsearch提供了很多内置的分词器,可以用来构建custom analyzers(自定义分词器)

为虚拟机的elasticsearch装ik分词器:

找到Releases · infinilabs/analysis-ik · GitHub对应的版本(我用的7.9.2)

解压放在ik文件夹里放进plugins目录下,重启elasticsearch服务

测试分词:

创建自定义词库:

下载nginx:

CentOS7下安装NGINX_centos7下载nginx-****博客,跟着这个步骤来,记得开防火墙的80端口,然后在/usr/local/nginx/html这个路径下新建es文件夹,fenci.txt,会出现乱码问题,后续解决;

配置ik分词器的远程词库地址:

来到ik的config文件夹:

至此,新词就可以添加进/usr/local/nginx/html/es文件夹下的fenci.txt

5.Elasticsearch-Rest-Client

新建模块:

修改配置文件,添加依赖:

新建config包,

添加common依赖,配置nacos注册中心:

启用服务注册发现:

引入ElasticSearch-Rest-Client的步骤;

1.在pom文件里导入依赖

2.给容器中注入一个RestHighLevelClient

3.参照官方API进行操作:Java High Level REST Client | Java REST Client [7.17] | Elastic

RequestOptions:请求设置项:

开始测试:

1.index:(保存更新都可以)

2.复杂检索:

1.先构造一个检索请求searchRequest

2.构造检索条件:

query条件构造:

聚合条件构造:嵌套使用 .subAggregation()

获取查询结果:

获取分析数据:

上一篇:【SpringBoot】Controller与Test


下一篇:20240718每日后端------------kafka VS RabbitMQ:选择正确的消息代理