谷粒商城高级篇-全文检索(ElasticSearch)

ES简介

学习文档地址:Elasticsearch Guide [7.16] | Elastic

什么是全文检索(ElasticSearch)?

全文检索属于最常见的需求,开源的ElasticSearch是目前全文检索引擎的首选。它可以快速的存储搜索分析海量数据。维基百科、StackOver Flow、Github都采用它。ElasticSearch的底层开源库Lucene。但是,你没有办法直接用Lucene,必须自己写代码去调用它的接口。ElasticSearch是Lucene的封装,提供了REST API 的操作接口,开箱即用。

ElasticSearch的用途

①应用程序搜索、网站搜索、企业搜索

②日志处理和分析

③基础设施指标和容器检测

④应用程序性能检测

⑤地理空间数据分析和可视化

⑥安全分析、业务分析

ElasticSearch的基本概念

1.索引(Index)

ES中的索引若当动词类比于Mysql的insert

ES中的索引若当名词类比于Mysql的database

2.类型(Type)

ES中的类型类比于Mysql中的table

3.文档(Document)

ES中的文档类比于Mysql中的记录,并且ES中的文档是json格式的数据

4.倒排索引

ES为什么能快速的进行全文检索的原因在于为数据创建倒排索引

什么是倒排索引?

将数据拆分为一个个的字或者多个词,并且为将含有某个字或词的数据添加这个字或词的索引中

例如:

相关性得分:用于将检索的数据进行一个排序,即看命中率

例如:检索红海特工行动,就会将红海特工行动分为红海、特工、行动三个词,会将1,2,3,4,5都检索出来,文档1是红海行动即命中了红海、行动两个词,即2中2肯定是排在第一位,文档2和文档3是3中2,文档4是2中1,文档5是4中2。

Docker安装ES

①设置虚拟机的内存大小

Vagrant 如何调整虚拟机的内存大小?_axfcjwkbi259888707的博客-CSDN博客

② 下载镜像文件

# 下载ES镜像文件,存储和检索数据
sudo docker pull  elasticsearch:7.4.2
# 下载可视化kibana镜像文件,可视化检索数据
sudo docker pull  kibana:7.4.2

③ 创建目录及配置

# 创建目录方便挂载
mkdir -p /mydata/elasticsearch/config
mkdir -p /mydata/elasticsearch/data
# 配置允许主机访问
echo " http.host: 0.0.0.0" >> /mydata/elasticsearch/config/elasticsearch.yml

 

④运行容器

docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx512m" \
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.4.2

9200是访问端口,9300是集群节点交流端口,ES_JAVA_OPTS="-Xms64m -Xmx512m" 设置ES的占用内存,-v设置映射文件

访问:http://192.168.56.22:9200

出现问题:访问拒绝

出现原因:文件权限不够,访问拒绝

# 查看容器日志
docker logs elasticsearch

解决方案: 将任意组任意成员的访问权限设置为rwx, - R :递归

chmod -R 777 /mydata/elasticsearch

重启容器

docker start [id]

看到以下界面,则说明ES安装成功:

设置ES开机自启动

sudo docker update elasticsearch --restart=always

安装kibana 

①创建容器,注意写自己的ip地址

docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.56.22:9200 -p 5601:5601 \
-d kibana:7.4.2

看到以下界面,则说明kibana安装成功

设置kibana开机自启动

sudo docker update kibana --restart=always

ES入门

ES-入门-_cat

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

② 查看ES的健康状况:GET /_cat/health

③查看主节点:GET /_cat/master

④ 查看所有索引:GET /_cat/indices

ES-入门-put&post新增数据 

索引一个文档(保存)

保存一个数据,保存在那个索引的那个类型下,指定用那个唯一标识

PUT请求保存文档

PUT /customer/external/1

再发送一次相同的请求就变成了更新 

将唯一标识去除则报错

说明:PUT请求必须携带唯一标识,若标识id不存在或者无数据则为新建,否则为更新

POST请求保存文档

再次发送相同的请求 ,变成更新状态 

不携带唯一标识,将会自动生成一个唯一标识

 ES-入门-get查询数据&乐观锁字段

模拟并发操作,一条请求想将name修改为1,一条请求想将name修改为2,判断依据就是?_seq_no=1&_primary_term=1

假设第一条请求先到达ES

第二条请求达到ES 

更新失败,修改_seq_no的值则更新成功

ES-入门-删除数据&bulk批量操作导入样本测试数据 

删除文档&索引

DELETE /customer/external/1
DELETE /customer

bulk批量API

语法规则

 两两一组

POST customer/external/_bulk
{"index":{"_id":"1"}}
{"name":"frank"}
{"index":{"_id":"2"}}
{"name":"kobe"}

使用kibana发送请求

 

彼此操作之间互不影响 

复杂实例测试

导入测试数据 

数据地址:登录 - Gitee.com

ES-进阶-两种查询方式

学习文档地址:Quick start | Elasticsearch Guide [7.16] | Elastic

①将请求参数放在uri路径之后

GET /bank/_search?q=*&sort=account_number:asc

q=*:查询所有,sort=account_number:asc即按account_number升序排列

took:ES执行搜索所花费的时间

timed_out:是否超时

_shards:告诉我们多少个分片被搜索了,以及统计了成功/失败的搜素分片

hits:搜索结果

hits.total:搜索结果

hits.hits:实际搜索结果数组(默认为前10文档)

sort: 结果的排序key(没有则按score排序)

_score:相关性得分(全文检索用)

max_score:最高得分(全文检索用)

②通过请求体方式访问

GET /bank/_search 
{ 
    "query" : { "match_all" : { } },
    "sort" : [ { "account_number" : "asc" } ] 
} 

ES-进阶-QueryDSL基本使用

QueryDSL的基本语法

基本语法:

{
    QUERY_NAME:{
       ARGUMENT:value,
       ARGUMENT:value,
       ...        
                }
}

from和size 类比mysql中limit即分页查询

返回部分属性

match全文检索 

match_all:匹配全部

match:全文检索

①检索字段非字符串则是精确匹配

无论是字符串"20"还是数字20,检索结果都是一样的 

 匹配字段是字符串类型则是全文检索

可以查出包含mill或者lane或者mill lane的文档,并且按照相关性得分进行一个排序 

match_phrase短语匹配

与match不同的是,不进行一个分词匹配,当作一个整体进行匹配

也可以使用keyword进行一个精确匹配 

 

match_phrase和keyword的区别: 

match_phrase:不区分大小写,包含匹配字段

  

 keyword:必须精确匹配

multi_match多字段匹配

多字段匹配会进行一个分词匹配

bool复合查询

must:一定满足

must_not:一定不满足

should:可满足不满足也行,但是满足了得分会更高

 

filter结果过滤

must和should会计算相关性得分,而filter并不会计算相关性得分

term查询 

match用于全文检索字段,term用于非全文检索字段即非文本字段

aggregations聚合分析 

聚合分析相当于mysql中的group by和聚合函数

语法规则:

"aggregations":{
    "<aggregations_name>":{
        "<aggregations_type>":{
            <aggregation_body>
        }
        [,"meta":{  [<meta_data_body>] }]?
        [,"aggregations":{ [<sub_aggregation>+ }]?

     }
    [,"<aggregation_name_2>":{...}]*
}

例题1:搜索address中包含mill的所有人的年龄分布以及平均年龄

terms:按照指定字段进行分组

avg:计算平均值

例题2:按照年龄聚合,并且请求这些年龄段人的平均工资

例题3: 查出所有年龄分布,并且这些年龄段中M的平均工资和F的平均工资以及这个年龄段的总体平均薪资

映射-mapping创建

什么是映射?

映射类比mysql中的定义列的数据类型

字段的数据类型:Field data types | Elasticsearch Guide [8.0] | Elastic

说明:ES7之后去掉了type

理由:

查看映射:GET bank/_mapping

说明: keyword是text的一个属性,text类型会进行全文检索而keyword是精确匹配并不会进行全文检索

动态映射:即由ES为你设置的字段类型

地址:Dynamic mapping | Elasticsearch Guide [8.0] | Elastic

显示映射:即自己定义字段的类型

地址:Explicit mapping | Elasticsearch Guide [8.0] | Elastic

创建字段映射

模板:

PUT /my-index-000001
{
  "mappings": {
    "properties": {
      "age":    { "type": "integer" },  
      "email":  { "type": "keyword"  }, 
      "name":   { "type": "text"  }     
    }
  }
}

添加一个字段到已存在映射中

说明:按照以上方式向已存在的映射中添加一个新的字段会报错

正确的方式:

PUT /my_index/_mapping
{
  "properties": {
    "employee-id": {
      "type": "keyword",
      "index": false
    }
  }
}

index为映射参数,控制该字段是否能被索引,默认为true

地址:index | Elasticsearch Guide [8.0] | Elastic

更新字段的映射:是不被允许的,只能创建一个新的索引进行数据迁移

数据迁移

地址:Reindex API | Elasticsearch Guide [8.0] | Elastic

6.0以后没有type的模板:

POST _reindex
{
  "source": {
    "index": "my-index-000001"
  },
  "dest": {
    "index": "my-new-index-000001"
  }
}

6.0以前的数据迁移的模板:

POST _reindex
{
  "source": {
    "index": "my-index-000001",
    "type":  "xxxx"
  },
  "dest": {
    "index": "my-new-index-000001"
  }
}

案例:将bank的数据迁移到newbank中

①创建一个新的索引

 ②进行一个数据迁移

分词&安装ik分词

什么是分词?

分词就是将一段话分成一个个词语

地址:Standard tokenizer | Elasticsearch Guide [8.1] | Elastic

案例:标准分词器

POST _analyze
{
  "tokenizer": "standard",
  "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}

结果:以空格将这句话分成一个个的单词

安装ik分词器

注意:不能用elasticsearch-plugin install  xxx.zip 进行自动安装

由于我们安装的ES是7.4.2,因此,我们安装的ik分词器版本要与ES对应

 下载地址:https://github.com/medcl/elasticsearch-analysis-ik/releases/tag/v7.4.2

安装ik分词器的步骤:

①进入ES容器内部的plugins目录,由于创建容器时进行了映射,因此,等价于进入mydata/elasticsearch/plugins目录

cd /mydata/elasticsearch/plugins

或者

docker exec -it 容器id /bin/bash

 ②下载ik分词器的zip

复制链接地址:https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.4.2/elasticsearch-analysis-ik-7.4.2.zip

 使用wget命令在线下载

wget ​​https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.4.2/elasticsearch-analysis-ik-7.4.2.zip

③解压

unzip 下载的文件
mv elasticsearch/ik

 查看是否安装好

cd ../bin
elasticsearch plugin list :即可列出系统的分词器

由于虚拟机网络或者很多命令没有设置好,后面会进行一个设置,为了方便后续的操作,这里我们安装xshell

下载地址:XShell免费版(解决官网打不开的问题)_QWQ___qwq的博客-CSDN博客_xshell不免费了吗

①要使用xshell需要进行权限认证,即开放权限认证

1.连接虚拟机:vagrant ssh
2.修改ssh配置文件: vi /etc/ssh/sshd_config
3.修改:PasswordAuthentication yes
4.重启服务:service sshd restart

②将解压好的ik压缩包传送到linux中

③修改文件权限

chmod -R 777 /ik

④重启容器

docker restart elasticsearch

⑤查看是否安装成功

1. docker exec -it 容器id /bin
3. elasticsearch-plugin list

如果出现ik则表示安装ik分词器成功

简单测试分词器

①ik_smart

 

②ik_max_word

 

补充:修改linux网络设置&开启root密码访问

修改linux网络设置

①cd /etc/sysconfig/network-scripts

② eth1即网卡1才是虚拟机的ip地址,因此,编辑ifcfg-eth1

vi ifcfg-eth1

③添加网关和dns

④网络服务重启

service network restart

修改linux的yum源

①备份yum源

mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup

②使用新yum源

curl -o /etc/yum.repos.d/CentOS7-163-Base.repo http://mirrors.163.com/.help/CentOS7-Base-163.repo
或
wget -O /etc/yum.repos.d/CentOS7-Aliyun.repo http://mirrors.aliyun.com/repo/Centos-7.repo

③生成缓存

yum makecache

下载wget和unzip

yum install -y wget
yum install -y unzip

分词-自定义词库

自定义的词库需要部署到Nginx中,因此,需要安装Nginx

安装nginx

①扩大虚拟机的内存大小

② 随便启动一个Nginx实例,目的是为了复制出配置文件

docker run -p 80:80 --name nginx  -d nginx:1.10

③将容器内的配置文件拷贝到当前目录

1. cd /mydata
2. mkdir nginx
#nginx与.之间有空格,"."别忘了
3. docker container cp nginx:/etc/nginx .
#删除原容器
4. docker stop nginx
5. docker rm nginx
#修改文件名
6. mv nginx conf
7. mkdir nginx
8. mv conf nginx

④创建新Nginx容器

docker run -p 80:80 --name nginx \
-v /mydata/nginx/html:/usr/share/nginx/html \
-v /mydata/nginx/logs:/var/log/nginx \
-v /mydata/nginx/conf:/etc/nginx \
-d nginx:1.10

⑤开机自启动

sudo docker update nginx --restart=always

出现以下页面则表示安装成功 

说明:nginx部署的页面都存在html中

在html下编写index.html

 

自定义词库

①在nginx中为ES创建存放的目录并设置词库

cd /mydata/nginx/html
#创建存放ik词库的目录
mkdir es
#创建词库
vi fenci.txt

 

 ②为ik分词器设置外部词库

cd /mydata/elasticsearch/plugins/ik/config
vi IKAnalyzer.cfg.xml

重启ES 

docker restart elasticsearch

测试

 

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值