栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

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

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

​视频网址

一.ElasticSearch 简介:(102~102)


1.介绍:
   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(数据库)。
   2)Type(类型)
在 Index(索引) 中,可以定义 一个/多个 Type(类型)。
类似于 Mysql 中的 Table,每一种类型的数据库,放在一起。
   3)文档 (document)
保存在 某个索引(index)下,某种类型(Type)下的一个数据(document)。
文档时 JSON 格式的。
文档(document)就像是,Mysql 中的某个 Table 里面的数据。
   4)图示


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)软件下载: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
 44 bootstrap.memory_lock: false
 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

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

vm.max_map_count=655360

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

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

    -7:重新加载:

sysctl -p

   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个,设置会报错****
 // 设置发现集群广播的地址
# 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
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 集群之 故障转移
   1)将 1个 data 节点 停止(down机)
结论:对集群没什么影响,会自动修复。
    -1:停止之前:

    -2:停止之后:
黄色状态:所有主节点可用,副本节点不完全可用。

    -3:停止一段时间:会自动修复

    -4:重启被停止的 data 节点一段时间后:

   2)将 master 节点停止(down机)
    -1:开始时:

    -2:master 停止:重新选举了,master 节点。

    -3:master 停止一段时间后:

    -4:重启 原 master 节点:(master节点 -> data 节点)

   3)脑裂问题:特别说明


6.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
}


2.索引一个文档(保存)
   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次,对资源状态改变的效果是等价的。无论对资源操作多少次,结果都是一样的。


3.查询文档:(使用乐观锁)
(避免修改时,并发修改,应携带:?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"
    }
}


4.更新文档(同时可新增属性)(局部更新 & 全量更新):
   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
}


5.删除文档 :
   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
}


6.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
      }
    }
  ]
}


7.样本测试数据(批量导入):
   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:精确匹配)


11.评分的计算规则:





五.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 安装

// 注意:不能用默认 elasticsearch-plugin install xxx.zip 进行自动安装。
// 下载网址:(同7.4.2版本)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 自带版本


    
        1.8
        7.4.2
    
    
        
            org.elasticsearch.client
            elasticsearch-rest-high-level-client
            7.4.2
        
    


    -2:编写配置类

@Configuration
public class ElasticSearchConfig {

    
    @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):

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/746169.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号