谷粒商城—全文检索—ElasticSearch2(102~127)

​视频网址

一.ElasticSearch 简介:(102~102)

1.介绍:

   1)Elasticsearch 解释:
    -1:elastic:有弹力的、可伸缩、灵活
    -2:search:查询
    -3:ElasticSearch:是一个【开源的、高扩展到、分布式的、RESTful 风格的全文搜索引擎】,能够解决不断涌现出的各种用例。
   1)Elasticsearch 和 Solr:区别?如何选择?
在这里插入图片描述
在这里插入图片描述
   1)全文搜索:属于最常见的需求,开源的 Elasticsearch 是目前,全文搜索引擎的首选。
   2)它可以快速的存储、搜索、和分析,海量的数据。
   3)Elastic 是对 Lucene 的封装,提供了 RESTful 风格API 的操作接口。开箱即用。
   4)官网:
    -1:官网文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
    -2:官网中文:https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html
在这里插入图片描述
在这里插入图片描述

2.用途:

在这里插入图片描述

3.基本概念:

   1)索引(Index)
动词:相当于 Mysql 中的 insert。
名次:相当于 Mysql 中的 DataBase(数据库)。
    -1:索引是 Elasticsearch 对逻辑数据的逻辑存储,所以它可以分为更小的部分。
    -2:可以把索引,看成关系型数据库的表,索引的结构,是为快速有效的全文索引准备的,特别是它不粗处原始值。
    -3:Elasticsearch 可以把索引,存放在一台机器,或者分散在多台服务器上。
    -4:每个索引可以有一个或多个分片(shard),每个分片可以有多个副本(replica)。
在这里插入图片描述

   2)类型(Type)(7.x 版本,已经废弃使用,默认类型为:_doc )
在 Index(索引) 中,可以定义 一个/多个 Type(类型)。
类似于 Mysql 中的 Table,每一种类型的数据库,放在一起。

   3)文档 (Document)
保存在 某个索引(index)下,某种类型(Type)下的一个数据(Document)。
文档是 JSON 格式的。文档就像是,Mysql 中的某个 Table 里面的数据。
    -1:存储在 Elasticsearch 中的,主要实体叫文档。用关系型数据库来类比的话,一个文档相当于数据库表中的一行记录。
    -2:Elasticsearch 和 MongoDB 中的文档类似,都可以有不同的结构,但 Elasticsearch 的文档只能够,相同字段必须有相同的类型。
    -3:文档由 多个字段组成,每个字段可能多次出现在一个文档里,这样的字段叫 多值字段(multivalued)。
    -4:每个字段的类型,可以是文本、数值、日期等。字段类型也可以是复杂类型,一个字段包含其他子文档 或者 数组。
在这里插入图片描述

   4)映射(mapping)
    -1:所有文档,写进索引之前,都会先进行分析,如何将输入的文本分割为词条、哪些词条又会被过滤,这种行为叫做映射。
    -2:一般由用户自己定义规则。

   5)文档类型
    -1:在 Elasticsearch 中,一个索引对象,可以存储很多不同用途的对象。例如,一个博客应用程序,可以保存文章和评论。
    -2:每个文档,可以有不同的结构。
    -3:不同的文档类型,不能为相同的属性值,设置不同的类型。例如:在同一索引中的所有文档类型中,一个叫 title 的字段,必须具有相同的类型。
   6)分片:
在这里插入图片描述
在这里插入图片描述
   7)副本(Replicas):
在这里插入图片描述
在这里插入图片描述
   8)图示:
在这里插入图片描述

4.检索原理:(倒排索引机制)

在这里插入图片描述

5.工作原理(官网)

在这里插入图片描述

6.索引是什么(官网)

在这里插入图片描述

7.LogStach 用途是什么(官网)

在这里插入图片描述




二.ElasticSearch 安装(103~104):

1.Docker 安装:

// 安装 Elasticsearch(存储和检索数据)
docker run -d \
-p 9200:9200 -p 9300:9300 \
--name es \
-e "discovery.type=single-node" \
elasticsearch:7.4.2

// 安装 Kibana(可视化检索数据)
docker run -d \
--name kibana \
-e ELASTICSEARCH_HOSTS=http://192.168.124.12:9200 \
-p 5601:5601 kibana:7.4.2

// 安装教程:
https://www.jianshu.com/p/ac3cf42dc95e

2.Linux 单节点部署

   1)软件下载(7.11.1):https://www.elastic.co/cn/downloads/elasticsearch
   2)安装:
    -1:解压软件:

// 解压缩
tar -zxvf elasticsearch-8.0.0-linux-x86_64.tar.gz

    -2:创建用户(因为安全问题,ES 不可用 root 用户运行使用)

-- 创建新的用户
useradd es  // 新增 es 用户
passwd es	// 为 es用户设置密码 (设置为了 es)

userdel -r es	// 如果错了,可以删除再添加
chown -R es:es /usr/local/elasticsearch/elasticsearch-7.11.0	// 文件夹所有者

    -3:修改配置文件:vim /config/elasticsearch.yml

 17 cluster.name: my-centos-01-elasticsearch-name	-- 识别集群到名女==名称
 23 node.name: node-1	

 33 path.data: /usr/local/elasticsearch/elasticsearch-7.11.1/data	-- 提前建好 数据目录
 37 path.logs: /usr/local/elasticsearch/elasticsearch-7.11.1/logs	-- 提前建好 日志目录

 57 node.master: true	-- 是不是有资格 选举 主节点
 58 node.data: true		-- 是不是有资格 选举 data 节点

 56 network.host: 192.168.31.136   -- 本机ip
 61 http.port: 9200
 73 cluster.initial_master_nodes: ["node-1", "node-2"]

    -4:修改配置文件:(末尾添加)vim /etc/security/limits.conf

-- 原因:es文件比较大,避免出现问题
-- 操作:设置每个进程,可以打开的文件数限制(打开的文件描述符的最大数目)
* soft nofile 65536
* hard nofile 65536

-- 解释:
	-- soft 指的是当前系统生效的设置值(警告)
	-- hard 表明系统中所能设定的最大值(错误)
	-- soft 的限制不能比hard 限制高

    -5:修改配置文件:(末尾添加)vim /etc/sysctl.conf

-- 更改一个进程能拥有的,最大最大内存区域限制
vm.max_map_count=655360
-- 禁用交换区
vm.swappiness=1

    -6:重新加载:

sysctl -p

    -7:修改配置文件:(末尾添加)vim /etc/security/limits.d/20-nproc.conf

-- 原因:es文件比较大,避免出现问题
-- 操作:设置每个进程,可以打开的文件数限制
  7 es soft nofile 65536
  8 es hard nofile 65536
-- 操作系统级别,对:每个用户创建的进程数的限制
* hard nproc 4096
-- 注:* 代表 Linux 所有用户名称

   3)启动软件,访问测试:http://192.168.124.11:9200/

su es  -- 不可使用 root 用户启动运行
cd /opt/elasticsearch/elasticsearch-8.0.0	-- 进入目录
/bin/elasticsearch		-- 启动
/bin/elasticsearch  -d		-- 后台启动

3.Linux 集群部署

   1)软件下载:同上
   2)集群节点(4种):Elasticsearch 集群,是由多个节点组成,通过:
  1、cluster.name:设置集群名称,并且用于区分其他的集群。
  2、node.name:每个节点,通过 node.name,指定节点的名称。
    -1:master 节点:
  1、配置文件中的 node.master 属性,设置为 true(默认为:true),就有资格被选为 master 节点。
  2、master 节点,用于控制整个集群的操作。比如:创建或删除索引、管理其他非 master 节点等。

    -2:data 节点:
  1、配置文件中 node.data 属性,设置为 true(默认为:true),就有资格被设置成 data 节点。
  2、data 节点,主要用于执行数据相关的操作。比如文档 CRUD。

    -3:客户端节点:
  1、配置文件中,node.master 属性 和 node.data 属性均为:false。则该节点为:客户端节点。
  2、该节点不能作为 master 节点,也不能作为 data 节点。
  3、可以作为客户端节点,用于响应用户的请求,把请求转发到其他节点。

    -4:部落节点:(连接其他集群)
  1、当一个节点,配置 tribe.* 的时候,它就是一个特殊的客户端。
  2、它可以连接多个集群,在所有连接的集群上,执行搜索和其他操作。

   3)搭建集群,软件安装:
    -1:解压缩

	-- 解压缩
tar -zxvf elasticsearch-7.11.0-linux-x86_64.tar.gz 
	-- 重命名
mv elasticsearch-7.11.0 es-cluster-01
	-- 关闭防火墙
systemctl stop firewalld

    -2:将软件分发到其他节点:(centos_02,centos_03)
  1、xsync es-cluster
  2、scp -r es-cluster elsearch@192.168.40.124:/usr/local/elasticsearch
    -3:创建用户:因为安全问题,ES 不允许 root 用户直接运行

	-- 新增 es 用户
useradd es 
	-- 为 es 用户设置密码
passwd es
	-- 如果错了,可以删除用户,再次添加
userdel -r es 
	-- 改变文件夹所有者
chown -R es:es /usr/local/elasticsearch/es-cluster/

    -4:修改配置文件:vim /usr/local/elasticsearch/es-cluster/config/elasticsearch.yml

-- 加入如下配置
 17 cluster.name: cluster-es	-- 集群名称(集群中保持一致)
 23 node.name: node-1	-- 节点名称,每个节点的名称,不能重复(node-2,node-3// (0.0.0.0)为任意网络均可访问。(或设置为本机 ip)
 // 在此设置为本机 ip 地址,每个节点的 ip 地址不能重复
 55 network.host: 192.168.124.11	
 57 node.master: true	-- 是不是有资格 选举 主节点
 58 node.data: true		-- 是不是有资格 选举 data 节点
 59 http.port: 9200		-- 访问端口
 
 // **** 以下2个,设置会报错****(集群中不做配置,会和 “initial_master_nodes” 冲突)
 // 设置发现集群广播的地址
-- 68 discovery.zen.ping.unicast.hosts: ["192.168.124.11","192.168.124.12","192.168.124.13"]
 // 设置成为 master 节点的最小节点数(目前3个节点,2个同意可成为主节点)
 // 很重要,否则会产生 “脑裂问题”。	= N/2 +1
 69 discovery.zen.minimum_master_nodes: 2
 
// head 插件,需要打开这两个配置(跨域)
 64 http.cors.allow-origin: "*"
 65 http.cors.enabled: true
 66 http.max_content_length: 200mb

// es7.x 之后新增的配置,节点发现(9300端口慢慢被废弃了)
 75 discovery.seed_hosts: ["192.168.124.11:9300", "192.168.124.12:9300", "192.168.124.13:9300"]
// es7.x 之后新增的配置,初始化一个新的集群时,需要此配置来选举 master
 79 cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]
 
 88 gateway.recover_after_nodes: 2
 89 network.tcp.keep_alive: true
 90 network.tcp.no_delay: true
 91 transport.tcp.compress: true
 
// 集群内,同时启动的数据任务个数,默认是2个
 94 cluster.routing.allocation.cluster_concurrent_rebalance: 16
// 添加或删除节点,及负载均衡时,并发恢复的线程个数,默认 4个
 95 cluster.routing.allocation.node_concurrent_recoveries: 16
// 初始化恢复数据时,并发恢复线程的个数,默认 4 个
 96 cluster.routing.allocation.node_initial_primaries_recoveries: 16

    -5:修改 vim /etc/security/limits.conf

* -> es
 62 * soft nofile 65536
 63 * hard nofile 65536                  

    -6:修改: vim /etc/security/limits.d/20-nproc.conf

// 调整最大文件描述
es soft nofile 65536
es hard nofile 65536
* soft nproc 2048
* hard nproc 4096

    -7:修改 & 重新加载:vim /etc/sysctl.conf

// 一个进程,在 VMAs(虚拟内存区域),创建内存映射最大数量
vm.max_map_count=655360
vm.swappiness = 1

sysctl -p	// 使配置生效

    -9: 修改 JVM 启动参数

// 说明:在 Elasticsearch 中,如果 network.host 不是 【localhost 或 127.0.0.1】 的话
// 就会被认为是生产环境,会对环境要求比较高,我们的测试环境不一定能满足,一般需要修改 JVM 启动参数。
-Xms128m	// 根据自己机器情况修改
-Xmx128m

   4)访问集群测试:GET:http://192.168.124.11:9200/_cat/nodes

192.168.124.13 9 96 45 1.74 1.11 0.59 cdhilmrstw - node-3
192.168.124.12 9 96 11 0.02 0.10 0.18 cdhilmrstw * node-2
192.168.124.11 7 96  9 0.29 0.26 0.25 cdhilmrstw - node-1

   5)集群状态查询:GET:192.168.124.11:9200/_cluster/health

{
    "cluster_name": "docker-cluster",	集群名称
    "status": "yellow",		-- 状态(解释如下)--
    "timed_out": false,		是否超时
    "number_of_nodes": 1,		节点数
    "number_of_data_nodes": 1,		数据节点数
    "active_primary_shards": 1,		活跃的主要的分片
    "active_shards": 1,		活跃度分片
    "relocating_shards": 0,		迁移分片
    "initializing_shards": 0,		初始化分片
    "unassigned_shards": 1,		未签名的分片
    "delayed_unassigned_shards": 0,		延迟的未签名的分片
    "number_of_pending_tasks": 0,		待定的任务数
    "number_of_in_flight_fetch": 0,		航班取来数量
    "task_max_waiting_in_queue_millis": 0,		任务在队列中最大等待毫秒数
    "active_shards_percent_as_number": 50.0		活跃分片占总数百分比
}

在这里插入图片描述
   6)访问 ES:GET:http://192.168.124.12:9200/
   7)访问 插件:GET:http://192.168.124.12:9200/
在这里插入图片描述
在这里插入图片描述
   8)访问 Kibana:GET:http://192.168.124.12:5601/

4.Linux 集群之 分片和副本

   1)介绍:
    -1:为了将数据,添加到 Elasticsearch,我们需要 索引(index)【一个存储关联数据的地方】。
    -2:实际上,索引只是一个用来指向,一个或多个分片(shards)的 “逻辑命名空间”(logical namespace)。

   2)分片:
    -1:一个分片(shard):是一个最小级别 “工作单元(worker unit)”,它只是保存了索引中,所有数据的一部分。
    -2:我们需要知道:分片就是一个 Lucene 实例。并且它本身,就是一个完整的搜索引擎。应用程序不会和它直接通信。
    -3:分片可以是主分片(primary shard),复制分片(副本)(replica shard)。
    -4:索引中的每个文档,属于一个单独的主分片,所以主分片的数量,决定了索引最多能存储多少数据。
    -5:复制分片,只是主分片的一个副本,它可以防止硬件故障,导致的数据丢失。同时可以提供读请求。(比如:搜索或者从别的 shard 取回文档)
    -6:当索引创建完成的时候,主分片的数量就固定了,但是复制分片的数量,可以随时调整。

5.Linux 集群之 故障转移

   安装 chrome 插件: Elasticsearch Head。
   1)将 1个 data 节点 停止(down机)
结论:对集群没什么影响,会自动修复。
    -1:停止之前:
绿色状态:表示所有 10 个分片(5 个主分片、5个副本分片)都在正常运行。
在这里插入图片描述
    -2:停止之后:
黄色状态:所有主节点可用,副本节点没有全部处于正常状态。
在这里插入图片描述
    -3:停止一段时间:会自动修复
在这里插入图片描述
    -4:重启被停止的 data 节点一段时间后:
在这里插入图片描述
   2)将 master 节点停止(down机)
    -1:开始时:
在这里插入图片描述
    -2:master 停止:重新选举了,master 节点。
在这里插入图片描述
    -3:master 停止一段时间后:
在这里插入图片描述
    -4:重启 原 master 节点:(master节点 -> data 节点)
在这里插入图片描述
   3)脑裂问题:特别说明
在这里插入图片描述

6.Linux 集群之 水平扩容

   1)如何扩容:
在这里插入图片描述
   2)
在这里插入图片描述
   3)如果:我们想要扩容,超过6个节点,怎么办呢?
在这里插入图片描述
在这里插入图片描述

7.Linux 集群之 分布式文档

   1)路由:(计算 存&取 位置)(数据 读&写 流程)
    -1:首先看个问题:写数据在集群中,该如何存储?
在这里插入图片描述
    -2:Elasticsearch 会采用计算的方式,来确定存储位置:
在这里插入图片描述
   2)文档的写操作:
    -1:新建、索引、和删除请求,都是写(write)操作,它们必须在主分片上,成功完成后,才能复制到相关的副本分片上。
在这里插入图片描述
    -2:执行顺序讲解:
在这里插入图片描述
   3)搜索文档(读操作)(单个文档)
    -1:文档 能够从,主分片 或 任意一个复制分片,被检索。
    -2:存在问题:
主分片接到写请求,刚写完主分片数据,未同步到副本分片。
此时新的查询,通过master,计算得到查询位置为副本分片,未能读取到数据,
此现象,为正常现象。
在这里插入图片描述
   4)全文搜索
    -1:对于全文搜索而言,文档可能分散在各个节点上,那么在分布式的情况下,如何搜索文档呢?
搜索分为2个阶段:搜索(query)+取回(fetch)
    -2:搜索(query)
在这里插入图片描述
    -3:取回(fetch)
在这里插入图片描述




三.ElasticSearch 入门—初步检索(RestAPI 风格)(105~109):

1._cat:

   1)查看所有节点(带 * 为主节点):

GET:http://192.168.124.12:9200/_cat/nodes

172.17.0.2 10 88 36 0.22 0.58 0.74 dilm * d81a418d4cbf

   2)查看 es 健康状况:

GET:http://192.168.124.12:9200/_cat/health

1645435075 09:17:55 docker-cluster green 1 1 4 4 0 0 0 0 - 100.0%

   3)查看主节点:

GET:http://192.168.124.12:9200/_cat/master

uGYfM7k-SS2gr4ccEUSGTA 172.17.0.2 172.17.0.2 d81a418d4cbf

   4)查看所有索引:(show databases)

GET:http://192.168.124.12:9200/_cat/indices?v

health status index                        uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   kibana_sample_data_ecommerce finsdf6wQPCavi8ph21uhQ   1   0       4675            0      4.9mb          4.9mb
green  open   .kibana_task_manager_1       ePuH1IaiSM6b-F5YSuoG0A   1   0          2            0     38.2kb         38.2kb
green  open   .apm-agent-configuration     l_mb-Xe6RFysKFQoKh5VMw   1   0          0            0       283b           283b
green  open   .kibana_1                    hBDzpOz5SlqwygosaPRdtw   1   0         54            0    933.5kb        933.5kb

2.索引(CRUD)

   1)创建非结构化索引:
(对比关系型数据库,创建索引,就等同于创建数据库)
   2)因为 PUT 请求是幂等性
(要求每次访问,返回结果都一样),第二次创建相同索引,会报错。

put /customer
// 参数
{
	"settings":{
		"index":{
			"number_of_shards":"2",	-- 设置分片数
			"number_of_replicas":"0",	-- 设置副本数
		}
	}
}
// 返回值
{
    "acknowledged": true,   承认
    "shards_acknowledged": true,   碎片_承认
    "index": "shopping"   索引
}

   2)删除索引:

DELETE:http://192.168.124.12:9200/customer
// 返回值
{
    "acknowledged": true
}

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

   1)保存一个数据,保存在 哪个索引的 哪个类型下,指定用哪一个唯一标识。
(PUT/POST /{索引}/{类型}/{id})(注意请求幂等性要求)
   2)customer 索引下,external 类型下,保存1号数据:
    -1:元数据(metadata):“_index”,“_type”,“_id” 等

PUT:http://192.168.124.12:9200/customer/external/1
// 数据为:
{
    "name":"john"
}

// 返回值为:带 “_”,称作为元数据
{
    "_index": "customer",	索引
    "_type": "external",	类型(可以是 大写/小写,不能包含“_” 或 “,”)
    "_id": "1",		id(可手动指定,否则自动生成【32位长度】)
    "_version": 1,	版本号(修改一次,版本号叠加)
    "result": "created",	请求结果,第二次发送为:update 更新操作
    "_shards": {	分片,集群再介绍
        "total": 2,		总数
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 0,	
    "_primary_term": 1
}

在这里插入图片描述
   3)直接保存文档,只使用 索引,不使用类型。
    Elasticsearch 7.x 版本中,Type 概念已经被删除了
    -1:发送请求:POST 192.168.124.11:9200/shopping/_doc(_doc 可变为 _create)
    -2:为什么是 POST ,而不是PUT?:
    答:数据创建成功后会返回 _id 属性,随机生成唯一性标识,每次都不一样。不符合幂等性要求。(PUT:幂等性行,不是幂等性也行)
    POST 为幂等性请求,每次返回数据都相同,所以不满足。
    -3:RESTful & JSON & Postman:
-:安全性:不会改变资源状态,可以理解为只读的;
-:幂等性:执行1次和执行N次,对资源状态改变的效果是等价的。无论对资源操作多少次,结果都是一样的。
在这里插入图片描述

4.查询文档:(使用乐观锁)

(避免修改时,并发修改,应携带:?if_seq_no=0&if_primary_term=1 )
(主键查询 和 DSL 查询,如下为主键查询)

GET:http://192.168.124.12:9200/customer/external/1	-- 主键查询
// 返回值:
{
    "_index": "customer",	索引
    "_type": "external",	类型
    "_id": "1",			记录 id
    "_version": 18,		版本号(被更新过18次)
    "_seq_no": 31,		并发控制字段,用来做乐观所操作(只要数据有改变,值会 +1"_primary_term": 1,	并发控制字段,用来做乐观所操作
    						(主分片发生变化【机器重启/重新选举】,值会 +1"found": true,		是否找到数据
    "_source": {		数据真实内容
        "name": "john"
    }
}

5.更新文档(同时可新增属性)(局部更新 & 全量更新):

   1)方式一:(局部更新,实际内部操作如下)
    -1:从旧文档中,检索JSON
    -2:修改它
    -3:删除旧文档
    -4:索引(插入)新文档

POST:http://192.168.124.12:9200/customer/external/1/_update
// 参数
{
    "doc":{
        "name":"张三"
    }
}
// 返回值:
{
    "_index": "customer",
    "_type": "external",
    "_id": "1",
    "_version": 25,
    "result": "updated",	操作结果(noop:没有做任何操作)
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 38,
    "_primary_term": 1
}

   2)方式二 & 方式三:(做全量的 覆盖修改)

PUT / POST:http://192.168.124.12:9200/customer/external/1

// 参数
{
    "name":"李四"
}

// 返回值
{
    "_index": "customer",
    "_type": "external",
    "_id": "1",
    "_version": 24,
    "result": "updated",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 37,
    "_primary_term": 1
}

6.删除文档 :

   1)说明:删除一个文档,也不会立即从磁盘中移除,他只是被标记为已删除状态。
Elasticsearch 将会在你之后,添加更多索引的时候,才会在后台进行删除内容的清理。

DELETE:http://192.168.124.12:9200/customer/external/1
// 返回值
{
    "_index": "customer",
    "_type": "external",
    "_id": "1",
    "_version": 32,
    "result": "deleted",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 45,
    "_primary_term": 1
}

7.bulk 批量 API:

   1)打开 Kibana,Dev Tools 界面
   2)发送请求:
在这里插入图片描述
   3)返回数据(每一条都单独返回存储信息,独立统计):

#! Deprecation: [types removal] Specifying types in bulk requests is deprecated.
{
  "took" : 4,
  "errors" : false,
  "items" : [
    {
      "index" : {
        "_index" : "customer2",
        "_type" : "external",
        "_id" : "1",
        "_version" : 2,
        "result" : "updated",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 2,
        "_primary_term" : 1,
        "status" : 200
      }
    },
    {
      "index" : {
        "_index" : "customer2",
        "_type" : "external",
        "_id" : "2",
        "_version" : 2,
        "result" : "updated",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 3,
        "_primary_term" : 1,
        "status" : 200
      }
    }
  ]
}

8.样本测试数据(批量导入):

   1)数据网址:
https://github.com/elastic/elasticsearch/blob/7.2/docs/src/test/resources/accounts.json?row=true
在这里插入图片描述




四.ElasticSearch 进阶检索(SearchAPI & Query DSL)(110~118)

一切方法,参照官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/7.4/index.html

1.SearchAPI:

   1)ES 目前支持两种基本检索方式:
    -1:使用 REST request URL,发送搜索参数(url + 检索参数)
    -2:使用 REST request body,来发送他们(url + 请求体)(也叫:QueryDSL
https://www.elastic.co/guide/en/elasticsearch/reference/7.4/getting-started-search.html

GET /bank/_search
// 参数
{
  "query": {
    "match_all": {}		匹配所有
  },
  "sort": [
    {
      "account_number": "asc"	按照账号升序排列
    }
  ]
}
// 返回值:
{
  "took" : 6,	Elasticsearch运行查询所用的时间,以毫秒为单位
  "timed_out" : false,	搜索请求是否超时
  "_shards" : {		搜索了多少碎片,以及成功、失败或跳过了多少碎片的明细。
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {		
      "value" : 1000,	全部的值-找到了多少匹配的文档
      "relation" : "eq"	检索关系
    },
    "max_score" : null,		找到的最相关文档的分数
    "hits" : [
      {
        "_index" : "bank",
        "_type" : "account",
        "_id" : "0",
        "_score" : null,	文档的相关性分数(使用match_all时不适用)
        "_source" : {
          "account_number" : 0,
          "balance" : 16623,
          "firstname" : "Bradshaw"
          .... 数据
        },
        "sort" : [	排序-文档的排序位置(不按相关性分数排序时)
          0
        ]
      }
    ]
  }
}

2.QueryDSL基本使用 & match等:

   1)QueryDSL 介绍:
在这里插入图片描述
    -1:一个查询语句的典型结构

{
	QUERY_NAME:{
		ARGUMENT:VALUE,
		ARGUMENT:VALUE,....
	}
}
-- 如果是针对某个字段,那么结构如下:
{
	QUERY_NAME:{
		FIELD_NAME:{
			ARGUMENT:VALUE,
			ARGUMENT:VALUE,....
		}
	}
}

   2)match_all:全部匹配
   3)match:限制检索条件
   4)from & size :分页:【公式:】
    -1:在集群系统中,深度分页:
在这里插入图片描述
   5)sort:排序
   6)_source:想要展示的字段
计算公式:(页码-1)* 每页数据条数

{
  "query": {
    "match_all": {}		查询全部
  },
  "sort": [
    {
      "account_number": "asc"	升序排序
    }
  ],
  "_source": ["account_number","balance"], 	查询显示的字段
  "from": 0,	分页:跳过开始的结果数
  "size": 1,	分页:每页显示条数
  "_source":{	想要展示的字段
	["title"]
  }
}

3.match 匹配查询(自动按 得分进行排序):(单词搜索 / 多词搜索)

   1)解释:
    -1:match 查询,是一个标准查询,不管你需要全文本查询 / 精确查询,基本上都要用到它。
    -2:如果使用 match 查询一个全文本字段,他会在真正查询之前,用分词器,先对要查询的字段进行分词后查询。
    -3:如果:match 下指定了一个确切值,【在遇到 数字、日期、布尔值、not_analyzed 的 字符串】时,它将为你准确匹配搜索你给定的值。
   2)匹配查询:基本类型(非字符串),精确匹配:

GET /bank/_search. (结果得分1.0{
  "query": {
    "match": {
      "balance": "16623"
    }
  }
}

   3)匹配查询:字符串,模糊匹配查询(全文检索):
   4)使用 ik 分词器后,多词搜索:多个词语,都需要匹配。
【可选择:“and” 和 “or” 的关系】(比较极端)。
在这里插入图片描述
   5)实际应用中,更多使用下面用法:
(设置匹配度)(通过实际中反复测试,确定合理的值)
【and:100%;or:0%】
在这里插入图片描述

4.match_phrase 短语匹配(自动按 得分进行排序):

   1)解释:将 需要匹配的词,当成一个整体单词(不分词)进行搜索。
   2)使用:

GET /bank/_search
{
  "query": {
    "match_phrase": {
      "address": "Madison Street"
    }
  }
}

5.multi_match 多字段匹配(自动按 得分进行排序):

   1)解释:匹配其中任意一个即可被查询出。
   2)使用:

GET /bank/_search
{
  "query": {
    "multi_match": {
      "query": "mill Brogan", 	可以进行分词。
      "fields": ["city","address"]	其中一个,有(mill / Brogan)即可被查询出
    }
  }
}

6.bool 复合查询 :

   1)bool 解释:查询可以用来合并多个条件查询结果的布尔逻辑,它包含以下操作符:
    -1:must:多个查询条件的完全匹配,相当于 and。
    -2:must_mot:多个查询条件的反匹配,相当于not。
    -3:should:如果匹配上,则得分更高,更优先显示。(可手动指定权重,会影响得分,详解在后面)
注意:如果查询语句中,没有 must,那么至少要有一个查询条件匹配,should 则相当于 or。(也可以通过 minmun_should_match 百分比参数进行控制)
在这里插入图片描述
    -4:这些参数,可以分别继承一个查询条件,或者一个查询条件的数组 [ ]。
   1)解释:复合语句,可以合并 任何其它查询语句,包括复合语句。
这就意味着,复合语句,可以互相嵌套,可以表达非常复杂的逻辑。
   2)使用:

GET /bank/_search
{
  "query": {
    "bool": {
      "must": [		必须满足,数组
        {
          "match": {
            "gender": "f"
          }
        },
        {
          "match": {
            "address": "Lane"
          }
        }
      ],
      "must_not": [		必须不满足
        {
          "match": {
            "balance": "38172"
          }
        }
      ],
      "should": [	满足其中任一条件即可
        {
          "match": {
            "address": "Lane"
          }
        }
      ]
    }
  }
}

7.filter 过滤 & range 范围查询 & exists 存在查询:

   1)filter 解释:并不是所有的查询,都需要产生分数,特别是那些仅用于 “filtering”(过滤)的文档。
为了【不计算分数】,Elasticsearch 会自动检查场景,并且优化查询的执行。
(过滤条件结果:无分数)
    -1:查询和过滤对比:
在这里插入图片描述
   2)range 解释:range 过滤,允许我们按照指定范围,查找一批数据。
    -1:gt:大于
    -2:gte:大于等于
    -3:lt:小于(LT)
    -4:lte:小于等于
   3)使用:

GET /bank/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "range": {	查询范围
            "age": {	年龄 大于等于10 并且 小于等于20
              "gte": 10,
              "lte": 20
            }
          }
        }
      ]
    }
  }
}

   4)exists 查询:
    -1:exists 查询:可以用于查找文档中是否包含指定字段,类似于 SQL 语句中的 IS_NULL 条件。
在这里插入图片描述

8.term 查询:

   1)解释:和 match 一样,匹配某个属性的值。文档全文检索字段用 match;其他非 text 字段匹配用 term。
(用于检索某些准确的值(用于精确匹配某些值)【例如:数字、日期、布尔值、price、id等】)。
   2)官网解释:https://www.elastic.co/guide/en/elasticsearch/reference/8.0/query-dsl-term-query.html
   3)请求事例:
在这里插入图片描述
   4)terms:批量匹配
在这里插入图片描述

9.权重:(在 bool 的 should 下使用)

   1)解释:有些时候,我们可能需要,对某些词语,增加权重,来影响该条数据的得分,从而达到优先显示的目的。
   2)使用:
在这里插入图片描述

10.highlight 高亮显示:

{
    "query": {
        "match_phrase": {
            "category": "小"
        }
    },
    "highlight":{		高亮查询显示(写法固定)
        "fields":{
            "category":{
                
            }
        }
    }
}

11.aggregations 聚合分析(分析功能):

   1)解释:
    -1:聚合,提供了从数据中分组和提取数据的能力。最简单的聚合方法,大致等于 SQL:GROUP BY 和 SQL 聚合函数。
    -2:在 Elasticsearch 中,您有执行搜索返回 hits(命中结果),并且同时返回聚合结果,把一个响应中的所有hits(命中结果)分割开的能力。
    -3:可以执行查询和多个聚合,并且在一次使用中,得到各自的(任何一个的)返回结果,使用一次简洁和简化的 API,来避免网络往返。
    -4:事例

{
    "aggs": { // 聚合操作
        "price_group": {    //名称,随意起名
            "terms": {  //分组
                "field": "price"    //分组字段
            }
        }
    },
    "size": 0
}
{
    "aggs": { // 聚合操作
        "price_avg": {    //名称,随意起名
            "avg": {  //平均值
                "field": "price"    //计算平均值字段
            }
        }
    },
    "size": 0
}

   2)使用(1):搜索 address 中包含 mill 的所有人的年龄分布,以及平均年龄,但不显示这些人的详情。
在这里插入图片描述
   3)使用(2):按照年龄聚合,并且请求这些年龄段的这些人的平均薪资
在这里插入图片描述
   4)使用(3):查出所有年龄分布,并且这些年龄段中 M 的平均薪资 和 F的平均薪资,以及这个年龄段的总体平均薪资。(gender.leyword:精确匹配)
在这里插入图片描述

12.评分的计算规则:

在这里插入图片描述





五.ElasticSearch 映射(119~121)

1.:创建映射

   1):字段类型(几乎涵盖了所有类型,详见官网)
   2):映射(Mapping)
    -1:前面我们创建的索引,以及插入数据,都是由 Elasticsearch 进行自动判断类型,但是有些时候,我们是需要进行,明确字段类型的,否则,自动判断的类型,和实际的需求是不相符的。
    -2:自动判断类型规则如下:
在这里插入图片描述
    -2:Elasticsearch 中,支持的类型如下:
在这里插入图片描述
    -3:Mapping 是用来定义一个文档(document),以及它所包含的属性(field),是如何存储和索引的。
   3):使用 Mapping 定义:
在这里插入图片描述
    -1:新增 mapping 信息(例如下面 2种方式)

{
    "properties": {
        "name": {
            "type": "text",		文本,可以分词
            "index": "true"		可以索引查询
        },
        "sex": {
            "type": "keyword",		不能够分词,必须完全匹配
            "index": true		可以索引查询
        }
    }
}

在这里插入图片描述
    -2:查看 mapping 信息:(/my_index/_mapping)
在这里插入图片描述

2.:添加新的字段映射(需指定索引)

在这里插入图片描述

3.:更新映射:对于,已经存在的映射字段,是不能更新的,更新必须创建新的索引,进行数据迁移。

4.:数据迁移

   1)查询要被修改的索引:
   2)复制老索引,修改,后创建新的索引:
   3)用如下方法,进行数据迁移:新迁移的数据,不会使用 type(已被取消)
在这里插入图片描述
在这里插入图片描述




六.ElasticSearch — ik分词(Analysis)(122~124)

1.:分词器 解释:

   1)什么是分词:就是指,讲一个文本,转化为一系列单词的过程,也叫文本分析。在 Elasticsearch 中,称之为 Analysis。
在这里插入图片描述

2.:安装 ik 分词器

   1)测试默认分词器如何分词:会将单词中的汉字,一个个提取出来,粗暴的分词。

GET _analyze
{
  "analyzer": "standard",	使用标准(默认)分词器
  "text": "第一"
}

   2)IK Analyzer 介绍:
    详见:git-readme:https://github.com/medcl/elasticsearch-analysis-ik/blob/master/README.md
在这里插入图片描述
   3)安装 ik 分词器:
    -1:docker 安装

// 注意:</font>不能用默认 elasticsearch-plugin install xxx.zip 进行自动安装。
// 下载网址:(同7.4.2版本)</font>https://github.com/medcl/elasticsearch-analysis-ik/releases?page=5
进入容器:docker exec -it d81a418d4cbf /bin/bash
安装插件:./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.4.2/elasticsearch-analysis-ik-7.4.2.zip

    -2:文件安装(ik版本一定要和 es版本一致,才可启动)

// https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.11.1/elasticsearch-analysis-ik-7.11.1.zip
// 1、将 下载的 elasticsearch-analysis-ik-6.5.4.zip,
//    解压到 /elasticsearch/plugins/ik 目录下即可。
mkdir /es/plugins/ik
unzip elasticsearch-analysis-ik-6.5.4.zip
// 重启 es
kill 进程号
./bin/elasticsearch

在这里插入图片描述

   4)测试分词效果:
在结果中,不仅可以看出分词结果,还返回了该词,在文本中的位置信息。
在这里插入图片描述

3.:自定义拓展词库

   1)修改 ik 分词器的配置文件(XML):
在这里插入图片描述

4.:通过 ik 分词器检索

   1)
   2)
   3)




七.ElasticSearch 整合 SpringBoot

1.:整合 high-level-client

   1)Elasticsearch 提供了 2种 REST 客户端。(9200 HTTP)(9300将被废弃)
    -1:Java Low Level REST client:
在这里插入图片描述
    -2:Java High Level REST client:
Elasticsearch-Rest-Client:官方 RestClient,封装了 ES 操作,提供了很多便捷的API,API 层次分明,上手简单。
官网:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/index.html

   2)整合开始(高版本):
    -1:引入 依赖(和 ES 版本相同),并修改 SpingBoot 自带版本

<?xml version="1.0" encoding="UTF-8"?>
    <properties>
        <java.version>1.8</java.version>
        <elasticsearch.version>7.4.2</elasticsearch.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.4.2</version>
        </dependency>
    </dependencies>
</project>

    -2:编写配置类

/**
 * @author zhangxudong@chunyu.me
 * @date 2022/2/22 5:34 下午
 */
@Configuration
public class ElasticSearchConfig {

    /**
     * 给容器中,注入 RestHighLevelClient
     */
    @Bean
    public RestHighLevelClient restHighLevelClient() {
        HttpHost http1 = new HttpHost("192.168.124.11", 9200, "http");
        HttpHost http2 = new HttpHost("192.168.124.12", 9200, "http");
        HttpHost http3 = new HttpHost("192.168.124.13", 9200, "http");
        RestClientBuilder builder = RestClient.builder(http1, http2, http3);
        RestHighLevelClient client = new RestHighLevelClient(builder);
        return client;
    }

}

    -3:使用

    @Autowired
    private RestHighLevelClient restHighLevelClient;

2.:保存测试

    @RequestMapping(value = "addIndex")
    public String addIndex() throws IOException {
        IndexRequest indexRequest = new IndexRequest("users").id("123");
        // 方式 1
//        indexRequest.source("username", "zhangsan", "age", 18, "gender", "男");

        // 方式2
        User user = new User("张三", 20);
        String jsonString = JSON.toJSONString(user);
        indexRequest.source(jsonString, XContentType.JSON);

        // 索引保存
        IndexResponse index = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);

        return "成功";
    }

3.:测试复杂检索

   1)简单查询:

    @RequestMapping(value = "/search")
    public String search() throws IOException {
        // 1:创建检索请求
        SearchRequest searchRequest = new SearchRequest();
        // 1.1:指定索引
        searchRequest.indices("bank");
        // 1.2:指定DSL,检索条件(求:不同年龄的平均薪资)
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.matchAllQuery())
                .aggregation(AggregationBuilders.terms("age_terms").field("age").size(10)
                        .subAggregation(AggregationBuilders.avg("balance_avg").field("balance")));

        System.out.println(sourceBuilder.toString());//打印检索条件
        searchRequest.source(sourceBuilder);

        // 2:获取检索信息
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println(searchResponse.toString());//打印查询结果
        return "成功";
    }

   2)结果分析:
    -1:转为map
    -2:使用 自带的 get 方法
    -3:封装为对象
   3):
   4):
   5):
   6):

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值