实战:安装ElasticSearch 和常用操作命令

概叙

科普文:深入理解ElasticSearch体系结构-CSDN博客

Elasticsearch各版本比较

 ElasticSearch 单点安装

1 创建普通用户

#1 创建普通用户名,密码
[root@hlink1 lyz]# useradd lyz
[root@hlink1 lyz]# passwd lyz#2 然后 关闭xshell  重新登录 ip 地址  用 lyz 用户登录#3 为 lyz 用户分配 sudoer 权限
[lyz@hlink1 ~]$ su
[lyz@hlink1 ~]$ vi /etc/sudoers
# 在 root  ALL=(ALL)    ALL 下面添加普通用户权限lyz  ALL=(ALL)    ALL

2 下载安装 ES

# 4 下载安装包
[lyz@hlink1 ~]$ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.15.2-linux-x86_64.tar.gz
# 5 解压安装包
[lyz@hlink1 ~]$ tar -xzf elasticsearch-7.15.2-linux-x86_64.tar.gz# 6 修改配置
[lyz@hlink1 ~]# cd elasticsearch-7.15.2/config
[lyz@hlink1 elasticsearch-7.15.2]# mkdir log
[lyz@hlink1 elasticsearch-7.15.2]# mkdir data
[lyz@hlink1 elasticsearch-7.15.2]# cd config
[lyz@hlink1 config]# rm -rf elasticsearch.yml
[lyz@hlink1 config]# vim elasticsearch.yml# 粘贴如下内容# 配置集群名称,保证每个节点的名称相同,如此就能都处于一个集群之内了
cluster.name: lyz-es
# # 每一个节点的名称,必须不一样
node.name: hlink1
path.data: /home/lyz/elasticsearch-7.15.2/log
path.logs: /home/lyz/elasticsearch-7.15.2/data
network.host: 0.0.0.0
# # http端口(使用默认即可)
http.port: 9200
# # 集群列表,你es集群的ip地址列表
discovery.seed_hosts: ["hlink1"]
# # 启动的时候使用一个master节点
cluster.initial_master_nodes: ["hlink1"]
bootstrap.system_call_filter: false
bootstrap.memory_lock: false
http.cors.enabled: true
http.cors.allow-origin: "*"

3 修改 jvm.option

修改 jvm.option 配置文件,调整 jvm 堆内存大小,每个人根据自己服务器的内存大小来进行调整

# 7 修改 jvm.option 配置文件
[lyz@hlink1 config]# vim jvm.options
-Xms2g
-Xmx2g

4 修改系统配置,解决启动问题

由于使用普通用户来安装 es 服务,且 es 服务对服务器的资源要求比较多,包括内存大小,线程数等。所以我们需要给普通用户解开资源的束缚

ES 因为需要大量的创建索引文件,需要大量的打开系统的文件,所以我们需要解除linux 系统当中打开文件最大数目的限制,不然 ES 启动就会抛错

进入 Root 用户

# 8 进入 root 用户
[lyz@hlink1 config]# su
Password:# 9 在最下面添加如下内容: 注意*不要去掉了
[root@hlink1 config]# sudo vim /etc/security/limits.conf* soft nofile 65536
* hard nofile 131072
* soft nproc 2048
* hard nproc 4096

5 普通用户启动线程数限制

修改普通用户可以创建的最大线程数

10 若为 Centos7,执行下面的命令
[root@hlink1 config]# sudo vim /etc/security/limits.d/20-nproc.conf# 找到如下内容:
* soft nproc 1024#修改为
* soft nproc 4096

6 普通用户调大虚拟内存

# 11 调大系统的虚拟内存
[root@hlink1 config]# vim /etc/sysctl.confvm.max_map_count=262144# 12 执行 sysctl -p
# 行完了 sysctl -p 若输出的结果和你配置的一样,说明配置成功了.
[root@hlink1 config]# sysctl -p
vm.max_map_count = 262144

7 启动 ES 服务

# 13 切换用户
[root@hlink1 config]# exit
exit
[lyz@hlink1 config]$# 直接启动 es 或者 后台启动 es
[lyz@hlink1 config]$ cd ..
[lyz@hlink1 elasticsearch-7.15.2]$ cd bin
# 直接启动
[lyz@hlink1 bin]$ ./elasticsearch 
# 后台启动 nohup ./elasticsearch 2>&1 &# 浏览器访问 http://hlink1:9200/?pretty

Elasticsearch集群搭建

一、环境配置

一主亮从;3节点

角色    IP地址    操作系统
master    99.99.10.30    CentOS Linux release 7.9.2009 (Core)
slave    99.99.10.31    CentOS Linux release 7.9.2009 (Core)
slave    99.99.10.32    CentOS Linux release 7.9.2009 (Core)
# Elasticsearch 不能以 root 用户运行,创建一个新用户并赋予适当权限。
sudo adduser es
​
sudo passwd 123456
​
sudo usermod -aG sudo es
# 调整 vm.max_map_count 参数,以满足 Elasticsearch 的需求。
sudo sysctl -w vm.max_map_count=262144
​
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf
# 增加文件描述符限制。
sudo echo "elasticsearch - nofile 65535" | sudo tee -a /etc/security/limits.conf
​
sudo echo "elasticsearch - nproc 4096" | sudo tee -a /etc/security/limits.conf
# 调整内存锁定:
sudo echo "elasticsearch soft memlock unlimited" | sudo tee -a /etc/security/limits.conf
​
sudo echo "elasticsearch hard memlock unlimited" | sudo tee -a /etc/security/limits.conf
# 安装java
sudo yum install java-11-openjdk-devel -y
​
# 配置 JAVA_HOME 环境变量(在.bash_profile 文件,添加以下内容)
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk
export PATH=$JAVA_HOME/bin:$PATH
​
# 然后重新加载配置:
source ~/.bashrc
​
#检查Java版本
java -version
​
openjdk version "11.0.23" 2024-04-16 LTS
OpenJDK Runtime Environment (Red_Hat-11.0.23.0.9-2.el7_9) (build 11.0.23+9-LTS)
OpenJDK 64-Bit Server VM (Red_Hat-11.0.23.0.9-2.el7_9) (build 11.0.23+9-LTS, mixed mode, sharing)


二、安装elasticsearch

es官方下载地址,es和kibana尽量下载同一版本

elasticsearch各版本下载地址

    https://www.elastic.co/cn/downloads/past-releases#elasticsearch

kibana (es的可视化管理工具)

    https://www.elastic.co/cn/downloads/past-releases/#kibana

# 解压elasticsearch包到/usr/local/下面:
tar -zxvf elasticsearch-7.10.0-linux-x86_64.tar.gz -C /usr/local/
​
#将elasticsearch-7.10.0重命名为es
cd /usr/local/
mv elasticsearch-7.10.0 es
​
# 这个文件夹用于存储 Elasticsearch 的数据,它将所有的索引数据和相关元数据存储在这个目录中
mkdir -p /data/elasticsearch_data/data
# 这个文件夹用于存储 Elasticsearch 的日志文件,记录了 Elasticsearch 的运行状态、错误信息和性能指标。
mkdir -p /data/elasticsearch_data/logs
​
sudo chown -R es:es /data/elasticsearch_data
sudo chmod -R 755 /data/elasticsearch_data
​
# 这个文件夹用于存储 Elasticsearch 的备份数据。
mkdir -p /opt/backup/es
mkdir -p /opt/backup/es1
​
sudo chown -R es:es /opt/backup/
sudo chmod -R 755 /opt/backup/


三、配置elasticsearch

1.先搭建单个节点,再复制到其他节点:

path.data: /opt/data
path.logs: /opt/logs#http访问端口,程序或kibana使用
http.port: 9200xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
# 尝试启动
./bin/elasticsearch
设置安全账号信息(ES要启动状态):执行以下命令,给各账号设置密码(演示使用的密码都为:123456), 整个集群只需要设置一次即可警告:设置账户密码切记要在单实例非集群模式时配置,不能添加任何集群的配置,否则会设置失败./bin/elasticsearch-setup-passwords interactive


2.集群配置:

cluster.name: elasticsearchnode.name: node1path.data: /data/elasticsearch_data/datapath.logs: /data/elasticsearch_data/logs#数据备份和恢复使用,可以一到多个目录
path.repo: ["/opt/backup/es", "/opt/backup/es1"]http.port: 9200#是否可以参与选举主节点
node.master: true#是否是数据节点
node.data: true#允许访问的ip,4个0的话则允许任何ip进行访问
network.host: 0.0.0.0#es各节点通信端口
transport.tcp.port: 9300#集群每个节点IP地址。
discovery.seed_hosts: ["99.99.10.30:9300", "99.99.10.31:9300", "99.99.10.32:9300"]#es7.x新增的配置,初始化一个新的集群时需要此配置来选举master
cluster.initial_master_nodes: ["node1", "node2", "node3"]#配置是否压缩tcp传输时的数据,默认为false,不压缩
transport.tcp.compress: true# 是否支持跨域,es-header插件使用
http.cors.enabled: true# *表示支持所有域名跨域访问
http.cors.allow-origin: "*"
http.cors.allow-headers: Authorization,X-Requested-With,Content-Type,Content-Length#集群模式开启安全 https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-minimal-setup.html
xpack.security.enabled: true
xpack.license.self_generated.type: basic
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: certs/elastic-certificates.p12
xpack.security.transport.ssl.keystore.password: "123456"
xpack.security.transport.ssl.truststore.password: "123456"#默认为1s,指定了节点互相ping的时间间隔。
discovery.zen.fd.ping_interval: 1s#默认为30s,指定了节点发送ping信息后等待响应的时间,超过此时间则认为对方节点无响应。
discovery.zen.fd.ping_timeout: 30s#ping失败后重试次数,超过此次数则认为对方节点已停止工作。
discovery.zen.fd.ping_retries: 3


四、复制elasticsearch到其他节点

scp -r /usr/local/es/ root@99.99.10.31:/usr/local/
scp -r /usr/local/es/ root@99.99.10.32:/usr/local/sudo chown -R es:es /usr/local/es/
sudo chmod -R 755 /usr/local/es/

五、测试elasticsearch集群

集群信息查看

# 切换到es用户
su es# 启动es
cd /usr/local/es/
./bin/elasticsearch# 查看集群信息
curl -XGET -u elastic:123456 "http://127.0.0.1:9200/_cluster/health?pretty"
{"cluster_name" : "elasticsearch","status" : "green","timed_out" : false,"number_of_nodes" : 3,"number_of_data_nodes" : 3,"active_primary_shards" : 1,"active_shards" : 2,"relocating_shards" : 0,"initializing_shards" : 0,"unassigned_shards" : 0,"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" : 100.0
}
这个 JSON 响应显示了 Elasticsearch 集群的健康状态及其一些关键指标。指标解读如下:集群基本信息
cluster_name: "elasticsearch"
集群的名称。这是你在 elasticsearch.yml 配置文件中指定的名称。
集群健康状态
status: "green"
集群的健康状态。可能的状态有三种:
green: 所有主分片和副本分片都是可用的。
yellow: 所有主分片都是可用的,但有一些副本分片不可用。
red: 有一些主分片不可用。
timed_out: false
表示查询是否超时。false 表示查询在规定时间内完成。节点和分片信息
number_of_nodes: 3
集群中的节点总数。这里表示集群中有 3 个节点。
number_of_data_nodes: 3
集群中的数据节点总数。数据节点存储数据并处理搜索请求。这里表示所有 3 个节点都是数据节点。分片状态
active_primary_shards: 1
当前活动的主分片数量。主分片是实际存储数据的分片。
active_shards: 2
当前活动的总分片数量,包括主分片和副本分片。这里有 1 个主分片和 1 个副本分片。
relocating_shards: 0
正在重新分配的分片数量。重新分配是指将分片从一个节点移动到另一个节点。
initializing_shards: 0
正在初始化的分片数量。这些分片正在被分配和恢复。
unassigned_shards: 0
未分配的分片数量。可能是因为没有足够的节点来分配这些分片。
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: 100.0
当前活动分片占所有分片的百分比。100% 表示所有分片都是活动的,没有分片是未分配的或初始化中的。

创建索引验证

# 创建一个索引看集群中每个节点索引数据
curl -XPUT -u elastic:123456 "http://127.0.0.1:9200/test-index"curl -XGET -u elastic:123456  "http://localhost:9200/_cat/indices?pretty"
green open test-index  _hNfQpNqTZWAsPKrqa51XA 1 1 0 0   416b   208b
green open .security-7 L6YSY_F0Sl207ijttvv4CQ 1 1 7 0 51.5kb 25.7kb


六、安装kibana和es-header插件:(可选)

# 下载kibana
wget https://artifacts.elastic.co/downloads/kibana/kibana-7.10.0-linux-x86_64.tar.gz# 解压到/usr/local/,并重命名为kibana
tar -zxvf kibana-7.10.0-linux-x86_64.tar.gz -C /usr/local/
cd /usr/local/
mv kibana-7.10.0-linux-x86_64/ kibana# 配置kibana,并加入下面的配置
vim /usr/local/kibana/config/kibana.yml
--------------------------------------
#设置为中文
i18n.locale: "zh-CN"
#允许其它IP可以访问
server.host: "0.0.0.0"
elasticsearch.username: "kibana_system"
elasticsearch.password: "elastic123"
#es集群地址,填写真实的节点地址
elasticsearch.hosts: ["http://xxx.xx.xx.xx:9200","http://xxx.xx.xx.xx:9200","http://xxx.xx.xx.xx:9200"]
--------------------------------------# 启动kibana
cd /usr/local/kibana/
./bin/kibana


es-head安装如下面的官方文档所示:

https://github.com/mobz/elasticsearch-head

七、Elasticsearch如何合理的设置分片:

科普文:深入理解ElasticSearch体系结构-CSDN博客

一、什么是分片

在 Elasticsearch 中,索引是由一个或多个分片组成的。每个分片是一个完整的 Lucene 索引,独立存储数据并执行搜索操作。通过分片,Elasticsearch 可以将数据分布到多个节点上,从而提高系统的吞吐量和容错能力。

二、分片的类型

主分片(Primary Shard):

  1. 每个索引默认包含的分片。
  2. 数据首先写入主分片,然后再复制到副本分片。
  3. 主分片的数量在索引创建时确定,之后不能更改。

副本分片(Replica Shard):

  1. 主分片的副本,用于提高数据的高可用性和搜索性能。
  2. 默认情况下,每个主分片有一份副本分片。
  3. 可以动态调整副本的数量。

三、分片的工作原理

数据分布:当你向 Elasticsearch 索引文档时,Elasticsearch 会根据文档的 ID 计算一个哈希值,并根据这个哈希值决定将文档存储到哪个主分片。这种方式确保了文档在主分片间的均匀分布。

数据存储:当你向 Elasticsearch 索引文档时,Elasticsearch 会根据文档的 ID 计算一个哈希值,并根据这个哈希值决定将文档存储到哪个主分片。这种方式确保了文档在主分片间的均匀分布。

数据存储:每个分片是一个独立的 Lucene 索引,包含多个倒排索引。这些倒排索引用于高效的全文搜索。分片将文档分成多个段(segment),每个段是一个不可变的索引文件。随着文档的添加,新的段会不断创建,旧的段会被合并以优化性能和存储空间。

数据副本:副本分片存储在不同的节点上,以防止单点故障。如果一个主分片节点故障,Elasticsearch 可以将副本分片升级为主分片,并继续提供服务。副本分片不仅用于故障恢复,还可以分担搜索请求的负载,从而提高查询性能。

请求处理

写请求(Indexing Request):

  1. 写请求首先发送到主分片。
  2. 主分片将数据写入自身,然后将数据复制到对应的副本分片。
  3. 所有分片都成功写入后,返回确认响应。

读请求(Search Request):

  1. 读请求可以发送到任意一个副本分片,包括主分片。
  2. 通过这种方式,读请求可以被均衡地分配到所有分片,提高查询性能。

四、分片的优点

水平扩展:通过增加分片和节点,可以轻松扩展 Elasticsearch 集群以处理更多数据和更高的查询负载。

高可用性:通过副本分片,Elasticsearch 提供了数据冗余,确保在节点故障时数据不会丢失。

高性能:分片使得搜索和索引请求可以并行处理,提高了系统的吞吐量。

五、分片如何设置

分片的官方建议:我在 Elasticsearch 集群内应该设置多少个分片? | Elastic Blog

1、分片过小会导致段过小,进而致使开销增加。您要尽量将分片的平均大小控制在至少几 GB 到几十 GB 之间。
对时序型数据用例而言,分片大小通常介于 20GB 至 40GB 之间。
 
2、由于单个分片的开销取决于段数量和段大小,所以通过 forcemerge 操作强制将
较小的段合并为较大的段能够减少开销并改善查询性能。理想状况下,
应当在索引内再无数据写入时完成此操作。请注意:这是一个极其耗费资源的操作,
所以应该在非高峰时段进行。 
 
3、每个节点上可以存储的分片数量与可用的堆内存大小成正比关系,但是 Elasticsearch并未
强制规定固定限值。这里有一个很好的经验法则:确保对于节点上已配置的每个 GB,将分片数量
保持在 20 以下。如果某个节点拥有 30GB 的堆内存,那其最多可有 600 个分片,但是在此限值范围内,您设置的分片数量越少,效果就越好。一般而言,这可以帮助集群保持良好的运行状态。
(编者按:从 8.3 版开始,我们大幅减小了每个分片的堆使用量,
因此对本博文中的经验法则也进行了相应更新。请按照以下提示了解 8.3+ 版本的 
Elasticsearch。)


在网上总结的:

每个分片的数据量不超过最大JVM堆空间设置,一般不超过32G。如果一个索引大概500G,那分片大概在16个左右比较合适。

单个索引分片个数一般不超过节点数的3倍,推荐是1.5 ~ 3倍之间。假如一个集群3个节点,根据索引数据量大小分片数在5-9之间比较合适。

主分片、副本和节点数,分配时也可以参考以下关系:节点数<= 主分片数 * (副本数 +1 )
创建索引时指定分片数量:

PUT /my_index
{
  "settings": {
    "index": {
      "number_of_shards": 3,
      "number_of_replicas": 1
    }
  }
}


Elasticsearch常用操作命令:

# es启动:./bin/elasticsearch# 访问地址:http://localhost:9200/ 默认9200端口# Kibana 启动:./bin/Kibana# 访问地址:http://localhost:5600/ 默认5600端口
# 查看集群状态
# 检查集群运行情况: 
curl -XGET -u elastic:123456 "http://127.0.0.1:9200/_cat/health?v"# 查看集群节点列表: 
curl -XGET -u elastic:123456 "http://127.0.0.1:9200/_cat/nodes"# 查看所有索引:       
curl -XGET -u elastic:123456 "http://127.0.0.1:9200/_cat/indices?v"
# 索引操作API
# 1.查询查看分片状态-Authorization方式(postman通过账密获取token)
curl -XGET ‘http://127.0.0.1:9200/_cluster/allocation/explain?pretty’ --header ‘Authorization’: Basic ZWxhc3RpYzphcDIwcE9QUzIw’# 2.查询查看分片状态-账密方式
curl -XGET -u elastic "http://127.0.0.1:9200/_cluster/allocation/explain?pretty" -H ‘Content-Type:application/json’# 3.查询集群状态命令
curl -XGET -u elastic:123456 "http://127.0.0.1:9200/_cluster/health?pretty"# 4.查询Es全局状态
curl -XGET -u elastic:123456 "http://127.0.0.1:9200/_cluster/stats?pretty"# 5.查询集群设置
curl -XGET -u elastic:123456 "http://127.0.0.1:9200/_cluster/settings?pretty"# 6.查询集群文档总数
curl -XGET -u elastic:123456 "http://127.0.0.1:9200/_cat/count?v"# 7.查看当前集群索引分片信息
curl -XGET -u elastic:123456 "http://127.0.0.1:9200/_cat/shards?v"# 8.查看集群实例存储详细信息
curl -XGET -u elastic "http://127.0.0.1:9200/_cat/allocation?v"# 9.查看当前集群的所有实例
curl -XGET -u elastic "http://127.0.0.1:9200/_cat/nodes?v"# 10.查看当前集群等待任务
curl -XGET -u elastic "http://127.0.0.1:9200/_cat/pending_tasks?v"# 11.查看集群查询线程池任务
curl -XGET -u elastic "http://127.0.0.1:9200/_cat/thread_pool/search?v"# 12.查看集群写入线程池任务
curl -XGET -u elastic "http://127.0.0.1:9200/_cat/thread_pool/bulk?v"# 13.清理ES所有缓存
curl -XPOST "http://127.0.0.1:9200/_cache/clear"# 14.查询索引信息
curl -XGET -u : ‘https://127.0.0.1:9200/licence_info_test?pretty’# 15.关闭索引
curl -XGET -u : ‘https://127.0.0.1:9200/my_index/_close?pretty’# 16.打开索引
curl -XGET -u : ‘https://127.0.0.1:9200/my_index/_open?pretty’

01 ES索引搜索查询(MySQL和ES对比)

简单梳理了一下ES JavaAPI的相关体系,感兴趣的可以自己研读一下源码。

02 词条查询

所谓词条查询,也就是ES不会对查询条件进行分词处理,只有当词条和查询字符串完全匹配时,才会被查询到。

2.1 等值查询-term

等值查询,即筛选出一个字段等于特定值的所有记录。

SQL:

1

select * from person where name = '张无忌';

而使用ES查询语句却很不一样(注意查询字段带上keyword):

1

2

3

4

5

6

7

8

9

10

11

GET /person/_search

{

 "query": {

  "term": {

   "name.keyword": {

    "value": "张无忌",

    "boost": 1.0

   }

  }

 }

}

ElasticSearch 5.0以后,string类型有重大变更,移除了string类型,string字段被拆分成两种新的数据类型: text用于全文搜索的,而keyword用于关键词搜索。

查询结果:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

{

  "took" : 0,

  "timed_out" : false,

  "_shards" : { // 分片信息

    "total" : 1, // 总计分片数

    "successful" : 1, // 查询成功的分片数

    "skipped" : 0, // 跳过查询的分片数

    "failed" : 0  // 查询失败的分片数

  },

  "hits" : { // 命中结果

    "total" : {

      "value" : 1, // 数量

      "relation" : "eq"  // 关系:等于

    },

    "max_score" : 2.8526313,  // 最高分数

    "hits" : [

      {

        "_index" : "person", // 索引

        "_type" : "_doc", // 类型

        "_id" : "1",

        "_score" : 2.8526313,

        "_source" : {

          "address" : "光明顶",

          "modifyTime" : "2021-06-29 16:48:56",

          "createTime" : "2021-05-14 16:50:33",

          "sect" : "明教",

          "sex" : "男",

          "skill" : "九阳神功",

          "name" : "张无忌",

          "id" : 1,

          "power" : 99,

          "age" : 18

        }

      }

    ]

  }

}

Java 中构造 ES 请求的方式:(后续例子中只保留 SearchSourceBuilder 的构建语句)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

/**

 * term精确查询

 *

 * @throws IOException

 */

@Autowired

private RestHighLevelClient client;

@Test

public void queryTerm() throws IOException {

 // 根据索引创建查询请求

    SearchRequest searchRequest = new SearchRequest("person");

    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

    // 构建查询语句

    searchSourceBuilder.query(QueryBuilders.termQuery("name.keyword", "张无忌"));

    System.out.println("searchSourceBuilder=====================" + searchSourceBuilder);

    searchRequest.source(searchSourceBuilder);

    SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);

    System.out.println(JSONObject.toJSON(response));

}

仔细观察查询结果,会发现ES查询结果中会带有_score这一项,ES会根据结果匹配程度进行评分。打分是会耗费性能的,如果确认自己的查询不需要评分,就设置查询语句关闭评分:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

GET /person/_search

{

 "query": {

  "constant_score": {

   "filter": {

    "term": {

     "sect.keyword": {

      "value": "张无忌",

      "boost": 1.0

     }

    }

   },

   "boost": 1.0

  }

 }

}

Java构建查询语句:

1

2

3

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

// 这样构造的查询条件,将不进行score计算,从而提高查询效率

searchSourceBuilder.query(QueryBuilders.constantScoreQuery(QueryBuilders.termQuery("sect.keyword", "明教")));

2.2 多值查询-terms

多条件查询类似 Mysql 里的IN 查询,例如:

1

select * from persons where sect in('明教','武当派');

ES查询语句:

1

2

3

4

5

6

7

8

9

10

11

12

GET /person/_search

{

 "query": {

  "terms": {

   "sect.keyword": [

    "明教",

    "武当派"

   ],

   "boost": 1.0

  }

 }

}

Java 实现:

1

2

3

4

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

// 构建查询语句

searchSourceBuilder.query(QueryBuilders.termsQuery("sect.keyword", Arrays.asList("明教", "武当派")));

}

2.3 范围查询-range

范围查询,即查询某字段在特定区间的记录。

SQL:

1

select * from pesons where age between 18 and 22;

ES查询语句:

1

2

3

4

5

6

7

8

9

10

11

12

13

GET /person/_search

{

 "query": {

  "range": {

   "age": {

    "from": 10,

    "to": 20,

    "include_lower": true,

    "include_upper": true,

    "boost": 1.0

   }

  }

 }

Java构建查询条件:

1

2

3

4

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

// 构建查询语句

searchSourceBuilder.query(QueryBuilders.rangeQuery("age").gte(10).lte(30));

}

2.4 前缀查询-prefix

前缀查询类似于SQL中的模糊查询。

SQL:

1

select * from persons where sect like '武当%';

ES查询语句:

1

2

3

4

5

6

7

8

9

10

{

 "query": {

  "prefix": {

   "sect.keyword": {

    "value": "武当",

    "boost": 1.0

   }

  }

 }

}

Java构建查询条件:

1

2

3

4

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

// 构建查询语句

searchSourceBuilder.query(QueryBuilders.prefixQuery("sect.keyword","武当"));

}

2.5 通配符查询-wildcard

通配符查询,与前缀查询类似,都属于模糊查询的范畴,但通配符显然功能更强。

SQL:

1

select * from persons where name like '张%忌';

ES查询语句:

1

2

3

4

5

6

7

8

9

10

{

 "query": {

  "wildcard": {

   "sect.keyword": {

    "wildcard": "张*忌",

    "boost": 1.0

   }

  }

 }

}

Java构建查询条件:

1

2

3

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

// 构建查询语句

searchSourceBuilder.query(QueryBuilders.wildcardQuery("sect.keyword","张*忌"));

03 负责查询

前面的例子都是单个条件查询,在实际应用中,我们很有可能会过滤多个值或字段。先看一个简单的例子:

1

select * from persons where sex = '女' and sect = '明教';

这样的多条件等值查询,就要借用到组合过滤器了,其查询语句是:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

{

 "query": {

  "bool": {

   "must": [

    {

        "term": {

      "sex": {

       "value": "女",

       "boost": 1.0

      }

     }

    },

    {

     "term": {

      "sect.keywords": {

       "value": "明教",

       "boost": 1.0

      }

     }

    }

   ],

   "adjust_pure_negative": true,

   "boost": 1.0

  }

 }

}

Java构造查询语句:

1

2

3

4

5

6

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

// 构建查询语句

searchSourceBuilder.query(QueryBuilders.boolQuery()

        .must(QueryBuilders.termQuery("sex", "女"))

        .must(QueryBuilders.termQuery("sect.keyword", "明教"))

);

3.1 布尔查询

布尔过滤器(bool filter)属于复合过滤器(compound filter)的一种 ,可以接受多个其他过滤器作为参数,并将这些过滤器结合成各式各样的布尔(逻辑)组合。

bool 过滤器下可以有4种子条件,可以任选其中任意一个或多个。filter是比较特殊的,这里先不说。

1

2

3

4

5

6

7

{

   "bool" : {

      "must" :     [],

      "should" :   [],

      "must_not" : [],

   }

}

  • must:所有的语句都必须匹配,与 ‘=’ 等价。
  • must_not:所有的语句都不能匹配,与 ‘!=’ 或 not in 等价。
  • should:至少有n个语句要匹配,n由参数控制。

精度控制:

所有 must 语句必须匹配,所有 must_not 语句都必须不匹配,但有多少 should 语句应该匹配呢?默认情况下,没有 should 语句是必须匹配的,只有一个例外:那就是当没有 must 语句的时候,至少有一个 should 语句必须匹配。

我们可以通过 minimum_should_match 参数控制需要匹配的 should 语句的数量,它既可以是一个绝对的数字,又可以是个百分比:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

GET /person/_search

{

 "query": {

  "bool": {

   "must": [

    {

     "term": {

      "sex": {

       "value": "女",

       "boost": 1.0

      }

     }

    }

   ],

   "should": [

    {

     "term": {

      "address.keyword": {

       "value": "峨眉山",

       "boost": 1.0

      }

     }

    },

    {

     "term": {

      "sect.keyword": {

       "value": "明教",

       "boost": 1.0

      }

     }

    }

   ],

   "adjust_pure_negative": true,

   "minimum_should_match": "1",

   "boost": 1.0

  }

 }

}

Java构建查询语句:

1

2

3

4

5

6

7

8

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

// 构建查询语句

searchSourceBuilder.query(QueryBuilders.boolQuery()

        .must(QueryBuilders.termQuery("sex", "女"))

        .should(QueryBuilders.termQuery("address.word", "峨眉山"))

        .should(QueryBuilders.termQuery("sect.keyword", "明教"))

        .minimumShouldMatch(1)

);

最后,看一个复杂些的例子,将bool的各子句联合使用:

1

select  * from persons where sex = '女' and age between 30 and 40 and sect != '明教' and (address = '峨眉山' OR skill = '暗器')

用 Elasticsearch 来表示上面的 SQL 例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

GET /person/_search

{

 "query": {

  "bool": {

   "must": [

    {

     "term": {

      "sex": {

       "value": "女",

       "boost": 1.0

      }

     }

    },

    {

     "range": {

      "age": {

       "from": 30,

       "to": 40,

       "include_lower": true,

       "include_upper": true,

       "boost": 1.0

      }

     }

    }

   ],

   "must_not": [

    {

     "term": {

      "sect.keyword": {

       "value": "明教",

       "boost": 1.0

      }

     }

    }

   ],

   "should": [

    {

     "term": {

      "address.keyword": {

       "value": "峨眉山",

       "boost": 1.0

      }

     }

    },

    {

     "term": {

      "skill.keyword": {

       "value": "暗器",

       "boost": 1.0

      }

     }

    }

   ],

   "adjust_pure_negative": true,

   "minimum_should_match": "1",

   "boost": 1.0

  }

 }

}

用Java构建这个查询条件:

1

2

3

4

5

6

7

8

9

10

11

12

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

// 构建查询语句

BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()

        .must(QueryBuilders.termQuery("sex", "女"))

        .must(QueryBuilders.rangeQuery("age").gte(30).lte(40))

        .mustNot(QueryBuilders.termQuery("sect.keyword", "明教"))

        .should(QueryBuilders.termQuery("address.keyword", "峨眉山"))

        .should(QueryBuilders.rangeQuery("power.keyword").gte(50).lte(80))

        .minimumShouldMatch(1);  // 设置should至少需要满足几个条件

// 将BoolQueryBuilder构建到SearchSourceBuilder中

searchSourceBuilder.query(boolQueryBuilder);

3.2 Filter查询

query和filter的区别:query查询的时候,会先比较查询条件,然后计算分值,最后返回文档结果;而filter是先判断是否满足查询条件,如果不满足会缓存查询结果(记录该文档不满足结果),满足的话,就直接缓存结果,filter不会对结果进行评分,能够提高查询效率。

filter的使用方式比较多样,下面用几个例子演示一下。

方式一,单独使用:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

{

 "query": {

  "bool": {

   "filter": [

    {

     "term": {

      "sex": {

       "value": "男",

       "boost": 1.0

      }

     }

    }

   ],

   "adjust_pure_negative": true,

   "boost": 1.0

  }

 }

}

单独使用时,filter与must基本一样,不同的是filter不计算评分,效率更高。

Java构建查询语句:

1

2

3

4

5

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

// 构建查询语句

searchSourceBuilder.query(QueryBuilders.boolQuery()

        .filter(QueryBuilders.termQuery("sex", "男"))

);

方式二,和must、must_not同级,相当于子查询:

1

select * from (select * from persons where sect = '明教')) a where sex = '女';

ES查询语句:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

{

 "query": {

  "bool": {

   "must": [

    {

     "term": {

      "sect.keyword": {

       "value": "明教",

       "boost": 1.0

      }

     }

    }

   ],

   "filter": [

    {

     "term": {

      "sex": {

       "value": "女",

       "boost": 1.0

      }

     }

    }

   ],

   "adjust_pure_negative": true,

   "boost": 1.0

  }

 }

}

Java:

1

2

3

4

5

6

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

// 构建查询语句

searchSourceBuilder.query(QueryBuilders.boolQuery()

        .must(QueryBuilders.termQuery("sect.keyword", "明教"))

        .filter(QueryBuilders.termQuery("sex", "女"))

);

方式三,将must、must_not置于filter下,这种方式是最常用的:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

{

 "query": {

  "bool": {

   "filter": [

    {

     "bool": {

      "must": [

       {

        "term": {

         "sect.keyword": {

          "value": "明教",

          "boost": 1.0

         }

        }

       },

       {

        "range": {

         "age": {

          "from": 20,

          "to": 35,

          "include_lower": true,

          "include_upper": true,

          "boost": 1.0

         }

        }

       }

      ],

      "must_not": [

       {

        "term": {

         "sex.keyword": {

          "value": "女",

          "boost": 1.0

         }

        }

       }

      ],

      "adjust_pure_negative": true,

      "boost": 1.0

     }

    }

   ],

   "adjust_pure_negative": true,

   "boost": 1.0

  }

 }

}

Java:

1

2

3

4

5

6

7

8

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

// 构建查询语句

searchSourceBuilder.query(QueryBuilders.boolQuery()

        .filter(QueryBuilders.boolQuery()

                .must(QueryBuilders.termQuery("sect.keyword", "明教"))

                .must(QueryBuilders.rangeQuery("age").gte(20).lte(35))

                .mustNot(QueryBuilders.termQuery("sex.keyword", "女")))

);

04 聚合查询

接下来,我们将用一些案例演示ES聚合查询。

4.1 最值、平均值、求和

案例:查询最大年龄、最小年龄、平均年龄。

SQL:

1

select max(age) from persons;

ES:

1

2

3

4

5

6

7

8

9

10

GET /person/_search

{

 "aggregations": {

  "max_age": {

   "max": {

    "field": "age"

   }

  }

 }

}

Java:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

@Autowired

private RestHighLevelClient client;

@Test

public void maxQueryTest() throws IOException {

 // 聚合查询条件

    AggregationBuilder aggBuilder = AggregationBuilders.max("max_age").field("age");

    SearchRequest searchRequest = new SearchRequest("person");

    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

    // 将聚合查询条件构建到SearchSourceBuilder中

    searchSourceBuilder.aggregation(aggBuilder);

    System.out.println("searchSourceBuilder----->" + searchSourceBuilder);

    searchRequest.source(searchSourceBuilder);

    // 执行查询,获取SearchResponse

    SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);

    System.out.println(JSONObject.toJSON(response));

}

使用聚合查询,结果中默认只会返回10条文档数据(当然我们关心的是聚合的结果,而非文档)。返回多少条数据可以自主控制:

1

2

3

4

5

6

7

8

9

10

11

GET /person/_search

{

 "size": 20,

 "aggregations": {

  "max_age": {

   "max": {

    "field": "age"

   }

  }

 }

}

而Java中只需增加下面一条语句即可:

1

searchSourceBuilder.size(20);

与max类似,其他统计查询也很简单:

1

2

3

4

AggregationBuilder minBuilder = AggregationBuilders.min("min_age").field("age");

AggregationBuilder avgBuilder = AggregationBuilders.avg("min_age").field("age");

AggregationBuilder sumBuilder = AggregationBuilders.sum("min_age").field("age");

AggregationBuilder countBuilder = AggregationBuilders.count("min_age").field("age");

4.2 去重查询

案例:查询一共有多少个门派。

SQL:

1

select count(distinct sect) from persons;

ES:

1

2

3

4

5

6

7

8

9

{

 "aggregations": {

  "sect_count": {

   "cardinality": {

    "field": "sect.keyword"

   }

  }

 }

}

Java:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

@Test

public void cardinalityQueryTest() throws IOException {

 // 创建某个索引的request

    SearchRequest searchRequest = new SearchRequest("person");

    // 查询条件

    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

    // 聚合查询

    AggregationBuilder aggBuilder = AggregationBuilders.cardinality("sect_count").field("sect.keyword");

    searchSourceBuilder.size(0);

    // 将聚合查询构建到查询条件中

    searchSourceBuilder.aggregation(aggBuilder);

    System.out.println("searchSourceBuilder----->" + searchSourceBuilder);

    searchRequest.source(searchSourceBuilder);

    // 执行查询,获取结果

    SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);

    System.out.println(JSONObject.toJSON(response));

}

4.3 分组聚合

4.3.1 单条件分组

案例:查询每个门派的人数

SQL:

1

select sect,count(id) from mytest.persons group by sect;

ES:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

{

 "size": 0,

 "aggregations": {

  "sect_count": {

   "terms": {

    "field": "sect.keyword",

    "size": 10,

    "min_doc_count": 1,

    "shard_min_doc_count": 0,

    "show_term_doc_count_error": false,

    "order": [

     {

      "_count": "desc"

     },

     {

      "_key": "asc"

     }

    ]

   }

  }

 }

}

Java:

1

2

3

4

5

6

SearchRequest searchRequest = new SearchRequest("person");

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

searchSourceBuilder.size(0);

// 按sect分组

AggregationBuilder aggBuilder = AggregationBuilders.terms("sect_count").field("sect.keyword");

searchSourceBuilder.aggregation(aggBuilder);

4.3.2 多条件分组

案例:查询每个门派各有多少个男性和女性

SQL:

1

select sect,sex,count(id) from mytest.persons group by sect,sex;

ES:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

{

 "aggregations": {

  "sect_count": {

   "terms": {

    "field": "sect.keyword",

    "size": 10

   },

   "aggregations": {

    "sex_count": {

     "terms": {

      "field": "sex.keyword",

      "size": 10

     }

    }

   }

  }

 }

}

4.4 过滤聚合

前面所有聚合的例子请求都省略了 query ,整个请求只不过是一个聚合。这意味着我们对全部数据进行了聚合,但现实应用中,我们常常对特定范围的数据进行聚合,例如下例。

案例:查询明教中的最大年龄。这涉及到聚合与条件查询一起使用。

SQL:

1

select max(age) from mytest.persons where sect = '明教';

ES:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

GET /person/_search

{

 "query": {

  "term": {

   "sect.keyword": {

    "value": "明教",

    "boost": 1.0

   }

  }

 },

 "aggregations": {

  "max_age": {

   "max": {

    "field": "age"

   }

  }

 }

}

Java:

1

2

3

4

5

6

7

SearchRequest searchRequest = new SearchRequest("person");

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

// 聚合查询条件

AggregationBuilder maxBuilder = AggregationBuilders.max("max_age").field("age");

// 等值查询

searchSourceBuilder.query(QueryBuilders.termQuery("sect.keyword", "明教"));

searchSourceBuilder.aggregation(maxBuilder);

另外还有一些更复杂的查询例子。

案例:查询0-20,21-40,41-60,61以上的各有多少人。

SQL:

1

2

3

4

5

6

7

select

 sum(case when age<=20 then 1 else 0 end) ageGroup1,

 sum(case when age >20 and age <=40 then 1 else 0 end) ageGroup2,

 sum(case when age >40 and age <=60 then 1 else 0 end) ageGroup3,

 sum(case when age >60 and age <=200 then 1 else 0 end) ageGroup4

from

 mytest.persons;

ES:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

{

 "size": 0,

 "aggregations": {

  "age_avg": {

   "range": {

    "field": "age",

    "ranges": [

     {

      "from": 0.0,

      "to": 20.0

     },

     {

      "from": 21.0,

      "to": 40.0

     },

     {

      "from": 41.0,

      "to": 60.0

     },

     {

      "from": 61.0,

      "to": 200.0

     }

    ],

    "keyed": false

   }

  }

 }

}

查询结果:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

"aggregations" : {

  "age_avg" : {

    "buckets" : [

      {

        "key" : "0.0-20.0",

        "from" : 0.0,

        "to" : 20.0,

        "doc_count" : 3

      },

      {

        "key" : "21.0-40.0",

        "from" : 21.0,

        "to" : 40.0,

        "doc_count" : 13

      },

      {

        "key" : "41.0-60.0",

        "from" : 41.0,

        "to" : 60.0,

        "doc_count" : 4

      },

      {

        "key" : "61.0-200.0",

        "from" : 61.0,

        "to" : 200.0,

        "doc_count" : 1

      }

    ]

  }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/51705.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kaggle使用api下载数据集

背景 kaggle通过api并配置代理下载数据集datasets 步骤 获取api key 登录kaggle&#xff0c;点个人资料&#xff0c;获取到自己的api key 创建好的key会自动下载 将key放至家目录下的kaggle.json文件中 我这里是windows的administrator用户。 装包 我用了虚拟环境 pip …

Vite + Vue3 + TS项目配置前置路由守卫

在现代前端开发中&#xff0c;使用 Vue 3 和 TypeScript 的组合是一种流行且高效的开发方式。Vite 是一个极速的构建工具&#xff0c;可以显著提升开发体验。本文博主将指导你如何在 Vite Vue 3 TypeScript 项目中配置前置路由守卫&#xff08;Navigation Guards&#xff09;…

【YashanDB知识库】如何远程连接、使用YashanDB?

问题现象 在各个项目实施中&#xff0c;我们经常遇到客户、开发人员需要连接和使用YashanDB但不知如何操作的问题&#xff0c;本文旨在介绍远程连接、使用YashanDB的几种方式。 问题的风险及影响 无风险 问题影响的版本 历史版本~23.2 问题发生原因 无 解决方法及规避方…

前端web开发HTML+CSS3+移动web(0基础,超详细)——第1天

一、开发坏境的准备 1&#xff0c;在微软商店下载并安装VS Code 以及谷歌浏览器或者其他浏览器&#xff08;我这里使用的是Microsoft Edge&#xff09; 2&#xff0c;打开vs code &#xff0c;在电脑桌面新建一个文件夹命名为code&#xff0c;将文件夹拖拽到vs code 中的右边…

Windows10安装CMake图文教程

CMake是一个跨平台的开源构建工具&#xff0c;用于管理软件构建过程。CMake允许开发人员使用简单的语法来描述项目的构建过程&#xff0c;而无需直接处理特定于操作系统或编译器的细节。开发人员可以编写CMakeLists.txt文件来指定项目的源文件、依赖项和构建规则&#xff0c;然…

Ubuntu 20.04.6 安装 Elasticsearch

1.准备 -- 系统更新 sudo apt update sudo apt upgrade -- 安装vim 文本编辑器 sudo apt install vim-- jdk 版本确认 java -versionjdk 安装可以参照&#xff1a;https://blog.csdn.net/CsethCRM/article/details/140768670 2.官方下载Elasticsearch 官方地址&#xff1a;h…

Tekion 选择 ClickHouse Cloud 提升应用性能和指标监控

本文字数&#xff1a;4187&#xff1b;估计阅读时间&#xff1a;11 分钟 作者&#xff1a;ClickHouse team 本文在公众号【ClickHouseInc】首发 Tekion 由前 Tesla CIO Jay Vijayan 于 2016 年创立&#xff0c;利用大数据、人工智能和物联网等技术&#xff0c;为其汽车客户解决…

2024电赛H题参考方案(+视频演示)——自动行使小车

目录 一、题目要求 二、参考资源获取 三、参考方案 1、环境搭建及工程移植 2、移植MPU6050模块 3、移植TB6612电机驱动模块 4、整体控制方案视频演示 总结 一、题目要求 小编自认为&#xff1a;此次H题属于控制类题目&#xff0c;相较于往年较为简单&#xff0c;功能也算单一&a…

谷歌出品,一款免费的智能绘图工具

AutoDraw是由Google开发的一款基于网络的智能绘图工具&#xff0c;旨在通过人工智能技术帮助用户快速、简便地创建图画和图表。该工具于2017年4月11日由谷歌创意实验室推出&#xff0c;并迅速获得了广泛关注。 AutoDraw的核心功能是利用机器学习算法识别用户的草图或涂鸦&…

分布式SQL查询引擎之Presto

Apache Presto 是一个开源的分布式 SQL 查询引擎&#xff0c;旨在高效地对大规模数据集执行交互式查询。Presto 最初由 Facebook 开发&#xff0c;现已成为广泛使用的数据查询工具&#xff0c;特别是在大数据和分析领域。 主要特点 高性能&#xff1a;Presto 通过并行化和内存…

【A1web 1.0】靶机复现详解!

靶机地址&#xff1a; https://www.vulnhub.com/entry/ai-web-1,353/攻击机&#xff1a;kali 首先虚拟机建一个A1web 1.0靶机 切换nat模式 然后kali扫描 nmap -sV ip段 0/24 扫描出ip进行访问 访问没有什么信息 使用dirb 对网页…

使用 Matlab 绘制带有纹理的柱状图

以下是效果 1. 在 Matlab 里安装两个额外的库&#xff1a; hatchfill2 和 legendflex。 &#xff08;1&#xff09;搜索并安装 hatchfill2&#xff0c;用来画纹理 (2) 搜索并安装 legendflex&#xff0c;用来画自定义的图例 2. 代码&#xff08;说明见注释&#xff09; data …

排序算法辨析(快速记忆版)(冒泡排序,选择排序,插入排序,希尔排序,归并排序,快速排序)保研面经

选择排序&#xff1a;摸到一叠牌&#xff0c;每次选择出最小的放在合适的位置&#xff08;第一次放在第一张&#xff0c;第二次放在第二张&#xff09;&#xff0c;实现排序 最好最坏都是 O&#xff08;n^2&#xff09; 插入排序&#xff1a;摸牌的时候一张一张摸&#xff0c;每…

每日Attention学习14——Efficient Self-Attention

模块出处 [MICCAI 22] [link] [code] Lesion-aware Dynamic Kernel for Polyp Segmentation 模块名称 Efficient Self-Attention (ESA) 模块作用 高效自注意力 模块结构 模块思想 Self Attention操作在具有优秀的长距离建模能力的同时&#xff0c;也有着较高的计算与内存成…

学习ruixingkafei过程

一、抓包 手机安装证书&#xff0c;开启VPN抓包&#xff0c;电脑上打开花瓶&#xff0c;在同一个局域网内抓包&#xff0c;这些老一套没什么可说的。 看看我们的抓包结果是不是很美丽&#xff0c;请求内容加密&#xff0c;返回内容也加密&#xff0c;猜测加密方式aes&#xff0…

JWT (JSON Web Token)

&#x1f3bc;个人主页&#xff1a;金灰 &#x1f60e;作者简介:一名简单的大一学生;易编橙终身成长社群的嘉宾.✨ 专注网络空间安全服务,期待与您的交流分享~ 感谢您的点赞、关注、评论、收藏、是对我最大的认可和支持&#xff01;❤️ &#x1f34a;易编橙终身成长社群&#…

AI绘画3分钟解决英文恐惧症,comfyui汉化插件

前言 全面解析&#xff1a;Comfy UI汉化插件的安装与配置指南 本文涉及的工作流和插件&#xff0c;需要的朋友请扫描免费获取哦 引言 本文图片来源网络&#xff0c;侵权联删除。 在全球化的今天&#xff0c;软件界面的本地化是提升用户体验的重要一环。对于许多非英语母语的…

EasyExcel入门

目录 一、文章简介 二、概念 1.EasyExcel是什么&#xff1f; 2.EasyExcel 能用在哪里&#xff1f; 3.为什么要选用EasyExcel解析excel&#xff1f; 4.如何使用EasyExcel&#xff1f; 三、EasyExcel快速入门 1.环境搭建 2.简单写excel 代码示例 TestFileUtil Employe…

心灵调整:音乐之美

音乐每天都在不同的空间和复杂的形式影响着人们。从电梯音乐削减尴尬的沉默,到家庭交通堵塞。音乐增强了人们所爱的人与人之间的瞬间,并帮助他们度过艰难时期。音乐被用于世界各地几代人的各种形式的治疗。本文进一步阐述了它如何在几种类型的心理健康状况中得到应用。 什么是音…

【SOC 芯片设计 DFT 学习专栏 -- DFT DRC规则检查】

请阅读【嵌入式及芯片开发学必备专栏】 请阅读【芯片设计 DFT 学习系列 】 如有侵权&#xff0c;请联系删除 转自&#xff1a; 芯爵ChipLord 2024年07月10日 12:00 浙江 文章目录 概述DRC的概念Tessent DRC检查的概述时钟相关检查扫描相关检查BIST规则检查预DFT时钟规则检查 …