实战:安装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.rhkb.cn/news/387892.html

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

相关文章

Nat Med·UNI:开启计算病理学新篇章的自监督基础模型|顶刊精析·24-07-31

小罗碎碎念 本期推文主题 这一期推文是病理AI基础模型UNI的详细介绍&#xff0c;原文如下。下期推文会介绍如何使用这个模型&#xff0c;为了你能看懂下期的推文&#xff0c;强烈建议你好好看看今天这期推文。 看完这篇推文以后&#xff0c;你大概就能清楚这个模型对自己的数据…

卷积神经网络(六)---实现 cifar10 分类

cifar10 数据集有60000张图片&#xff0c;每张图片的大小都是 32x32 的三通道的彩色图&#xff0c;一共是10种类别、每种类别有6000张图片&#xff0c;如图4.27所示。 图 4.27 cifar数据集 使用前面讲过的残差结构来处理 cifar10 数据集&#xff0c;可以实现比较高的准确率。 …

麦田物语第十五天

系列文章目录 麦田物语第十五天 文章目录 系列文章目录一、构建游戏的时间系统二、时间系统 UI 制作总结 一、构建游戏的时间系统 在该游戏中我们要构建年月日天时分秒等时间的概念&#xff0c;从而实现季节的更替&#xff0c;昼夜的更替等&#xff08;不同的季节可以播种不同…

【MATLAB源码】机器视觉与图像识别技术实战示例文档---鱼苗面积预测计数

系列文章目录 第一篇文章&#xff1a;【MATLAB源码】机器视觉与图像识别技术—视觉系统的构成(视频与图像格式转换代码及软件下载) 第二篇文章&#xff1a;【MATLAB源码】机器视觉与图像识别技术(2)—图像分割基础 第三篇文章&#xff1a;【MATLAB源码】机器视觉与图像识别技术…

提交高通量测序处理数据到 GEO --- 操作流程

❝ 写在前面 由于最近在提交课题数据到 NCBI 数据库&#xff0c;整理了相关笔记。本着自己学习、分享他人的态度&#xff0c;分享学习笔记&#xff0c;希望能对大家有所帮助。推荐先按顺序阅读往期内容&#xff1a; 1. 提交高通量测序数据到 GEO --- 说明书 2. 提交高通量测序原…

jQuery前端网页制作

1、Jquery的概述 1.1JavaScript库 JavaScript 高级程序设计(特别是对浏览器差异的复杂处理),通常很困难也很耗时。 为了应对这些调整,许多的 JavaScript (helper) 库应运而生。 这些 JavaScript 库常被称为 JavaScript 框架。 市面上一些广受欢迎的 JavaScript 框架:…

基于Docker搭建ELK

目录 1.系统操作 2.搭建es 3.kibana(新起终端跟es一起启动) 4.logstash&#xff08;新起终端和es一起启动&#xff09; 5.修改logstash配置文件 6. 创建索引 7. exit #退出容器 8. 在logstash节点插入数据&#xff0c;测试是否能拿取到&#xff08;下面如果本身有数据…

基于多种机器学习的豆瓣电影评分预测与多维度可视化【可加系统】

有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主 在本研究中&#xff0c;我们采用Python编程语言&#xff0c;利用爬虫技术实时获取豆瓣电影最新数据。通过分析豆瓣网站的结构&#xff0c;我们设计了一套有效的策略来爬取电影相关的JSON格式数据。…

[FBCTF2019]RCEService (PCRE回溯绕过和%a0换行绕过)

json格式输入ls出现index.php 这道题原本是给了源码的&#xff0c;BUUCTF没给 源码&#xff1a; <?phpputenv(PATH/home/rceservice/jail);if (isset($_REQUEST[cmd])) {$json $_REQUEST[cmd];if (!is_string($json)) {echo Hacking attempt detected<br/><br/…

ElasticSearch学习篇15_《检索技术核心20讲》进阶篇之TopK检索

背景 学习极客实践课程《检索技术核心20讲》https://time.geekbang.org/column/article/215243&#xff0c;文档形式记录笔记。 相关问题&#xff1a; ES全文检索是如何进行相关性打分的&#xff1f;ES中计算相关性得分的时机?如何加速TopK检索&#xff1f;三种思路 精准To…

eclipse ui bug

eclipse ui bug界面缺陷&#xff0c;可能项目过多&#xff0c;特别maven项目过多&#xff0c;下载&#xff0c;自动编译&#xff0c;加载更新界面异常 所有窗口死活Restore不回去了 1&#xff09;尝试创建项目&#xff0c;还原界面&#xff0c;失败 2&#xff09;关闭所有窗口&…

Python写UI自动化--playwright(pytest.ini配置)

在 pytest.ini 文件中配置 playwright 的选项可以更好地控制测试执行的过程。 在终端输入pytest --help&#xff0c;可以找到playwright的配置参数 目录 1. --browser{chromium,firefox,webkit} 2. --headed 3. --browser-channelBROWSER_CHANNEL 4. --slowmoSLOWMO 5. …

Photos框架 - 自定义媒体选择器(UI列表)

​​​​​​​Photos框架 - 自定义媒体资源选择器&#xff08;数据部分&#xff09; Photos框架 - 自定义媒体选择器&#xff08;UI列表&#xff09;​​​​​​​ Photos框架 - 自定义媒体选择器&#xff08;UI预览&#xff09; Photos框架 - 自定义媒体选择器&#xff0…

规划决策算法(四)---Frenet坐标系

知乎&#xff1a;坐标系转换 1.Frenet 坐标系 什么是 Frenet 坐标系&#xff1a; 为什么使用 Frenet 坐标系&#xff1a; 通常情况&#xff0c;我们只会关注车辆当前距离左右车道线的距离&#xff0c;来判断是否偏离车道&#xff0c;是否需要打方向盘进行方向微调。而不是基于…

【YashanDB知识库】yasdb jdbc驱动集成BeetISQL中间件,业务(java)报autoAssignKey failure异常

问题现象 BeetISQL中间件版本&#xff1a;2.13.8.RELEASE 客户在调用BeetISQL提供的api向yashandb的表中执行batch insert并将返回sequence设置到传入的java bean时&#xff0c;报如下异常&#xff1a; 问题的风险及影响 影响业务流程正常执行&#xff0c;无法获得batch ins…

matlab仿真 数字信号载波传输(下)

&#xff08;内容源自详解MATLAB&#xff0f;SIMULINK 通信系统建模与仿真 刘学勇编著第七 章内容&#xff0c;有兴趣的读者请阅读原书&#xff09; clear all M8; msg[1 4 3 0 7 5 2 6]; ts0.01; T1; %t0:ts:T; t0:ts:T-ts; %x0:ts:length(msg); x0:ts:length(msg)-ts; f…

决策树基础

概述 决策树是一种树型结构&#xff0c;其中每个内部结点表示在一个属性上的测试&#xff0c;每个分支代表一 个测试输出&#xff0c;每个叶结点代表一种类别。决策树学习采用的是自顶向下的递归方法&#xff0c;其基本思想是以信息熵为度量构造一棵熵值下降最快的树&#xff…

一层5x1神经网络绘制训练100轮后权重变化的图像

要完成这个任务&#xff0c;我们可以使用Python中的PyTorch库来建立一个简单的神经网络&#xff0c;网络结构只有一个输入层和一个输出层&#xff0c;输入层有5个节点&#xff0c;输出层有1个节点。训练过程中&#xff0c;我们将记录权重的变化&#xff0c;并在训练100轮后绘制…

github简单地操作

1.调节字体大小 选择options 选择text 选择select 选择你需要的参数就可以了。 2.配置用户名和邮箱 桌面右键&#xff0c;选择git Bash Here git config --global user.name 用户名 git config --global user.email 邮箱名 3.用git实现代码管理的过程 下载别人的项目 git …

反爬虫限制:有哪些方法可以保护网络爬虫不被限制?

目前&#xff0c;爬虫已经成为互联网数据获取最主流的方式。但为了保证爬虫顺利采集数据&#xff0c;需要防范网站的反爬虫机制&#xff0c;降低IP被限制的风险&#xff0c;这样才能提高爬虫工作的效率。那么&#xff0c;如何防止网络爬虫被限制呢&#xff1f;下面介绍几种有效…