目录1. 简介2. 环境要求3. 安装前准备4. 安装 Elasticsearch5. 配置 Elasticsearch6. 启动与管理服务7. 验证安装8. 基本使用9. 安全配置10. 性能优化11. 常见问题与解决方案12. 备份与恢复1. 简介Elasticsearch 是一个基于 Apache Lucene 的开源分布式搜索和分析引擎，适用于所有类型的数据，包括文本、数字、地理空间、结构化和非结构化数据。主要特性分布式架构：自动分片和副本管理RESTful API：通过 HTTP 进行交互近实时搜索：索引后几乎立即可搜索全文检索：强大的文本搜索和分析能力高可用性：支持集群和自动故障转移2. 环境要求2.1 硬件要求组件最低配置推荐配置CPU2核4核以上内存4GB16GB以上磁盘10GB100GB以上 SSD网络100Mbps1Gbps💡 资源受限环境说明如果您的服务器配置为 2核2G，Elasticsearch 仍然可以运行，但需要进行以下调整：JVM 堆内存：设置为 512MB-1GB（不超过物理内存的50%）索引分片数：减少分片数量，单节点环境建议设置为1索引副本数：设置为0（单节点无需副本）刷新间隔：增加到30s或更长，减少资源消耗数据量限制：建议数据量不超过10GB并发请求：限制并发查询数，避免OOM# 2核2G 环境推荐的 JVM 配置 -Xms512m -Xmx1g2.2 软件要求操作系统：CentOS 7/8、Ubuntu 18.04/20.04/22.04、RHEL 7/8Java：JDK 11 或更高版本（Elasticsearch 8.x 自带 OpenJDK）依赖包：glibc 2.17 或更高版本2.3 系统参数要求最大文件描述符：至少 65535最大线程数：至少 4096虚拟内存：至少 2621443. 安装前准备3.1 创建 Elasticsearch 用户# 创建 elasticsearch 用户组和用户 sudo groupadd elasticsearch sudo useradd -g elasticsearch -s /bin/bash -m elasticsearch # 设置密码（可选） sudo passwd elasticsearch3.2 配置系统参数3.2.1 修改文件描述符限制# 编辑 limits.conf sudo vim /etc/security/limits.conf # 添加以下内容 elasticsearch soft nofile 65535 elasticsearch hard nofile 65535 elasticsearch soft nproc 4096 elasticsearch hard nproc 40963.2.2 修改虚拟内存# 编辑 sysctl.conf sudo vim /etc/sysctl.conf # 添加以下内容 vm.max_map_count=262144 # 使配置生效 sudo sysctl -p3.2.3 禁用 Swap（推荐）# 临时禁用 sudo swapoff -a # 永久禁用，编辑 /etc/fstab，注释掉 swap 行 sudo vim /etc/fstab # 注释掉类似这样的行： # /dev/mapper/centos-swap swap swap defaults 0 03.3 安装 Java（如果需要）# CentOS/RHEL sudo yum install java-11-openjdk java-11-openjdk-devel -y # Ubuntu/Debian sudo apt update sudo apt install openjdk-11-jdk -y # 验证 Java 安装 java -version4. 安装 Elasticsearch4.1 方法一：使用 RPM 包安装（CentOS/RHEL）4.1.1 导入 GPG 密钥sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch4.1.2 创建 Yum 仓库选项 A：官方源（国外）sudo vim /etc/yum.repos.d/elasticsearch.repo添加以下内容：[elasticsearch] name=Elasticsearch repository for 8.x packages baseurl=https://artifacts.elastic.co/packages/8.x/yum gpgcheck=1 gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch enabled=1 autorefresh=1 type=rpm-md选项 B：清华大学镜像源（国内推荐） 🇨🇳sudo vim /etc/yum.repos.d/elasticsearch.repo添加以下内容：[elasticsearch] name=Elasticsearch repository for 8.x packages baseurl=https://mirrors.tuna.tsinghua.edu.cn/elasticstack/yum/elastic-8.x/ gpgcheck=1 gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch enabled=1 autorefresh=1 type=rpm-md选项 C：阿里云镜像源（国内备用） 🇨🇳sudo vim /etc/yum.repos.d/elasticsearch.repo添加以下内容：[elasticsearch] name=Elasticsearch repository for 8.x packages baseurl=https://mirrors.aliyun.com/elasticstack/yum/elastic-8.x/ gpgcheck=1 gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch enabled=1 autorefresh=1 type=rpm-md4.1.3 安装 Elasticsearchsudo yum install elasticsearch -y4.2 方法二：使用 DEB 包安装（Ubuntu/Debian）4.2.1 导入 GPG 密钥wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg4.2.2 安装 apt-transport-httpssudo apt-get install apt-transport-https -y4.2.3 添加 APT 仓库选项 A：官方源（国外）echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list选项 B：清华大学镜像源（国内推荐） 🇨🇳echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://mirrors.tuna.tsinghua.edu.cn/elasticstack/apt/8.x stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list选项 C：阿里云镜像源（国内备用） 🇨🇳echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://mirrors.aliyun.com/elasticstack/apt/8.x stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list4.2.4 安装 Elasticsearchsudo apt-get update sudo apt-get install elasticsearch -y4.3 方法三：使用 tar.gz 包安装（通用）4.3.1 下载 Elasticsearch选项 A：官方源（国外）# 切换到 elasticsearch 用户 su - elasticsearch # 下载最新版本（以 8.11.0 为例） cd /opt sudo wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.11.0-linux-x86_64.tar.gz # 解压 sudo tar -xzf elasticsearch-8.11.0-linux-x86_64.tar.gz # 重命名（可选） sudo mv elasticsearch-8.11.0 elasticsearch # 修改所有者 sudo chown -R elasticsearch:elasticsearch /opt/elasticsearch选项 B：清华大学镜像源（国内推荐） 🇨🇳# 下载最新版本（以 8.11.0 为例） cd /opt sudo wget https://mirrors.tuna.tsinghua.edu.cn/elasticstack/downloads/elasticsearch/elasticsearch-8.11.0-linux-x86_64.tar.gz # 解压 sudo tar -xzf elasticsearch-8.11.0-linux-x86_64.tar.gz # 重命名（可选） sudo mv elasticsearch-8.11.0 elasticsearch # 修改所有者 sudo chown -R elasticsearch:elasticsearch /opt/elasticsearch选项 C：华为云镜像源（国内备用） 🇨🇳# 下载最新版本 cd /opt sudo wget https://mirrors.huaweicloud.com/elasticsearch/8.11.0/elasticsearch-8.11.0-linux-x86_64.tar.gz # 解压和配置同上 sudo tar -xzf elasticsearch-8.11.0-linux-x86_64.tar.gz sudo mv elasticsearch-8.11.0 elasticsearch sudo chown -R elasticsearch:elasticsearch /opt/elasticsearch💡 下载速度慢的解决方案如果下载速度很慢，可以使用迅雷等下载工具下载后上传到服务器：# 在本地Windows下载后，使用scp上传 scp elasticsearch-8.11.0-linux-x86_64.tar.gz root@你的服务器IP:/opt/4.4 重要：保存初始密码和令牌安装完成后，系统会自动生成以下信息，请务必保存：✅ Elasticsearch security features have been automatically configured! ✅ Authentication is enabled and cluster connections are encrypted. ℹ️ Password for the elastic user (reset with `bin/elasticsearch-reset-password -u elastic`): lhQpLELkjkrawaBoaz0Q ℹ️ HTTP CA certificate SHA-256 fingerprint: a52dd93511e8c6645e2c2e2e03aa98a2b3e4dc81c71c5e82c99f8efff3526f6c ℹ️ Configure Kibana to use this cluster: • Run Kibana and click the configuration link in the terminal when Kibana starts. • Copy the following enrollment token and paste it into Kibana in your browser: eyJ2ZXIiOiI4LjExLjAiLC... 安装日志Selecting previously unselected package elasticsearch. (Reading database ... 104136 files and directories currently installed.) Preparing to unpack .../elasticsearch_8.19.6_amd64.deb ... Unpacking elasticsearch (8.19.6) ... Setting up elasticsearch (8.19.6) ... --------------------------- Security autoconfiguration information ------------------------------ Authentication and authorization are enabled. TLS for the transport and HTTP layers is enabled and configured. The generated password for the elastic built-in superuser is : d8Yoo5g5g*TFbcAFpJSg If this node should join an existing cluster, you can reconfigure this with '/usr/share/elasticsearch/bin/elasticsearch-reconfigure-node --enrollment-token <token-here>' after creating an enrollment token on your existing cluster. You can complete the following actions at any time: Reset the password of the elastic built-in superuser with '/usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic'. Generate an enrollment token for Kibana instances with '/usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana'. Generate an enrollment token for Elasticsearch nodes with '/usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s node'. ------------------------------------------------------------------------------------------------- ### NOT starting on installation, please execute the following statements to configure elasticsearch service to start automatically using systemd sudo systemctl daemon-reload sudo systemctl enable elasticsearch.service ### You can start elasticsearch service by executing sudo systemctl start elasticsearch.service✅ Elasticsearch 8.19.6 安装日志分析（完成配置后使用这里只是分析！！！）📊 安装概况版本：Elasticsearch 8.19.6 (amd64)安装方式：DEB 包安装安装状态：✅ 成功完成当前状态：⚠️ 未启动（需要手动启动）🔐 重要安全信息🔑 超级管理员密码（务必保存！）用户名：elastic 密码：d8Yoo5g5g*TFbcAFpJSg⚠️ 警告：这是系统自动生成的密码，只显示一次，必须立即保存！🛡️ 安全特性（已自动配置）✅ 认证和授权：已启用✅ TLS 加密：传输层和 HTTP 层都已启用✅ 证书：已自动生成和配置🚀 下一步操作1️⃣ 启动服务（必须执行）# 重新加载 systemd 配置 sudo systemctl daemon-reload # 设置开机自启动 sudo systemctl enable elasticsearch.service # 启动 Elasticsearch 服务 sudo systemctl start elasticsearch.service # 查看服务状态 sudo systemctl status elasticsearch.service2️⃣ 验证安装（等待 15-30 秒后执行）# 使用自动生成的密码测试连接 curl -k -u elastic:d8Yoo5g5g*TFbcAFpJSg https://localhost:9200 # 查看集群健康状态 curl -k -u elastic:d8Yoo5g5g*TFbcAFpJSg https://localhost:9200/_cluster/health?pretty3️⃣ 查看日志（如果启动失败）# 查看实时日志 sudo journalctl -u elasticsearch -f # 查看最近 50 条日志 sudo journalctl -u elasticsearch -n 50🛠️ 可用的管理命令重置 elastic 用户密码sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic生成 Kibana 连接令牌（如需安装 Kibana）sudo /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana生成新节点加入令牌（如需搭建集群）sudo /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s node重新配置节点（加入现有集群）sudo /usr/share/elasticsearch/bin/elasticsearch-reconfigure-node --enrollment-token <令牌>📁 重要文件路径类型路径配置文件/etc/elasticsearch/elasticsearch.yml数据目录/var/lib/elasticsearch日志目录/var/log/elasticsearch证书目录/etc/elasticsearch/certs主程序目录/usr/share/elasticsearch可执行文件/usr/share/elasticsearch/bin/⚠️ 注意事项密码保存：d8Yoo5g5g*TFbcAFpJSg 必须立即保存到安全的地方服务未启动：安装后不会自动启动，需要手动执行启动命令HTTPS 访问：由于启用了 TLS，访问时需要使用 https:// 而不是 http://证书验证：测试时可以使用 -k 参数跳过证书验证，生产环境建议使用正确的证书防火墙：确保防火墙允许 9200 和 9300 端口🎯 快速启动检查清单[ ] 保存 elastic 用户密码：d8Yoo5g5g*TFbcAFpJSg[ ] 执行 sudo systemctl daemon-reload[ ] 执行 sudo systemctl enable elasticsearch.service[ ] 执行 sudo systemctl start elasticsearch.service[ ] 等待 15-30 秒[ ] 测试连接：curl -k -u elastic:d8Yoo5g5g*TFbcAFpJSg https://localhost:9200[ ] 检查集群健康状态现在可以执行启动命令了！ 🚀5. 配置 Elasticsearch5.1 主配置文件位置RPM/DEB 安装：/etc/elasticsearch/elasticsearch.ymltar.gz 安装：/opt/elasticsearch/config/elasticsearch.yml5.2 基本配置sudo vim /etc/elasticsearch/elasticsearch.yml5.2.1 集群和节点配置# 集群名称 cluster.name: my-elasticsearch-cluster # 节点名称 node.name: node-1 # 节点角色（可选配置） node.roles: [ master, data, ingest ] # 数据和日志路径 path.data: /var/lib/elasticsearch path.logs: /var/log/elasticsearch💡 2核2G 环境额外配置建议# 限制线程池大小（降低资源消耗） thread_pool.write.queue_size: 200 thread_pool.search.queue_size: 500 # 降低缓存大小 indices.queries.cache.size: 5% indices.requests.cache.size: 1% # 限制字段数据缓存 indices.fielddata.cache.size: 15%5.2.2 网络配置# 绑定的网络地址 # 0.0.0.0 表示所有网络接口，生产环境建议指定具体 IP network.host: 0.0.0.0 # HTTP 端口 http.port: 9200 # TCP 传输端口 transport.port: 93005.2.3 发现和集群配置# 单节点模式（开发环境） discovery.type: single-node # 集群模式（生产环境） # discovery.seed_hosts: ["192.168.1.101", "192.168.1.102", "192.168.1.103"] # cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]5.2.4 内存配置编辑 JVM 配置文件：sudo vim /etc/elasticsearch/jvm.options或对于 tar.gz 安装：vim /opt/elasticsearch/config/jvm.options配置堆内存（建议设置为物理内存的 50%，但不超过 32GB）：# 示例：8GB 物理内存 -Xms4g -Xmx4g # 示例：2GB 物理内存（资源受限环境） -Xms512m -Xmx1g5.3 目录权限设置# RPM/DEB 安装 sudo chown -R elasticsearch:elasticsearch /var/lib/elasticsearch sudo chown -R elasticsearch:elasticsearch /var/log/elasticsearch sudo chown -R elasticsearch:elasticsearch /etc/elasticsearch # tar.gz 安装 sudo chown -R elasticsearch:elasticsearch /opt/elasticsearch5.4 2核2G 环境完整配置示例如果您的服务器是 2核2G 配置，这里提供一个完整的优化配置方案：5.4.1 elasticsearch.yml 配置# 集群配置 cluster.name: my-es-cluster node.name: node-1 discovery.type: single-node # 网络配置 network.host: 0.0.0.0 http.port: 9200 # 路径配置 path.data: /var/lib/elasticsearch path.logs: /var/log/elasticsearch # 性能优化（2核2G 专用） indices.queries.cache.size: 5% indices.requests.cache.size: 1% indices.fielddata.cache.size: 15% thread_pool.write.queue_size: 200 thread_pool.search.queue_size: 500 # 安全配置（可选：关闭以节省资源） xpack.security.enabled: false xpack.security.http.ssl.enabled: false xpack.security.transport.ssl.enabled: false5.4.2 jvm.options 配置# 堆内存设置（2GB 物理内存） -Xms512m -Xmx1g # GC 配置 -XX:+UseG1GC -XX:G1ReservePercent=25 # 其他优化 -XX:+AlwaysPreTouch -Xss1m -Djava.awt.headless=true5.4.3 创建索引时的建议设置curl -k -X PUT "https://localhost:9200/your_index" \ -H 'Content-Type: application/json' \ -d '{ "settings": { "number_of_shards": 1, "number_of_replicas": 0, "refresh_interval": "30s", "translog.durability": "async", "translog.sync_interval": "30s" } }'6. 启动与管理服务6.1 使用 Systemd 管理（RPM/DEB 安装）6.1.1 启动服务# 启动 Elasticsearch sudo systemctl start elasticsearch # 设置开机自启动 sudo systemctl enable elasticsearch # 查看服务状态 sudo systemctl status elasticsearch6.1.2 停止和重启服务# 停止服务 sudo systemctl stop elasticsearch # 重启服务 sudo systemctl restart elasticsearch # 重新加载配置 sudo systemctl daemon-reload6.1.3 查看日志# 查看实时日志 sudo journalctl -u elasticsearch -f # 查看最近的日志 sudo journalctl -u elasticsearch -n 100 # 查看日志文件 sudo tail -f /var/log/elasticsearch/my-elasticsearch-cluster.log6.2 手动启动（tar.gz 安装）# 切换到 elasticsearch 用户 su - elasticsearch # 后台启动 /opt/elasticsearch/bin/elasticsearch -d -p pid # 停止（使用保存的 pid） kill `cat /opt/elasticsearch/pid` # 查看日志 tail -f /opt/elasticsearch/logs/my-elasticsearch-cluster.log7. 验证安装7.1 检查服务状态# 等待服务启动（通常需要 10-30 秒） sleep 15 # 使用 curl 检查（需要身份验证） curl --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic:你的密码 https://localhost:9200 # 或者禁用 SSL 验证（仅测试用） curl -k -u elastic:你的密码 https://localhost:92007.2 预期输出{ "name" : "node-1", "cluster_name" : "my-elasticsearch-cluster", "cluster_uuid" : "xxxxxxxxxxxxxxxxxxx", "version" : { "number" : "8.11.0", "build_flavor" : "default", "build_type" : "tar", "build_hash" : "xxxxxxx", "build_date" : "2023-11-04T10:04:57.184859352Z", "build_snapshot" : false, "lucene_version" : "9.8.0", "minimum_wire_compatibility_version" : "7.17.0", "minimum_index_compatibility_version" : "7.0.0" }, "tagline" : "You Know, for Search" }7.3 查看集群健康状态curl -k -u elastic:你的密码 https://localhost:9200/_cluster/health?pretty健康状态说明：green：所有主分片和副本分片都可用yellow：所有主分片可用，但部分副本分片不可用red：部分主分片不可用8. 基本使用8.1 索引操作8.1.1 创建索引# 创建一个名为 "products" 的索引 curl -k -X PUT "https://localhost:9200/products" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "settings": { "number_of_shards": 1, "number_of_replicas": 0 }, "mappings": { "properties": { "name": { "type": "text" }, "price": { "type": "float" }, "description": { "type": "text" }, "created_at": { "type": "date" } } } }'8.1.2 查看索引# 查看所有索引 curl -k -u elastic:你的密码 "https://localhost:9200/_cat/indices?v" # 查看特定索引信息 curl -k -u elastic:你的密码 "https://localhost:9200/products?pretty"8.1.3 删除索引curl -k -X DELETE "https://localhost:9200/products" \ -u elastic:你的密码8.2 文档操作8.2.1 添加文档# 自动生成 ID curl -k -X POST "https://localhost:9200/products/_doc" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "name": "笔记本电脑", "price": 5999.00, "description": "高性能办公笔记本", "created_at": "2025-11-03" }' # 指定 ID curl -k -X PUT "https://localhost:9200/products/_doc/1" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "name": "台式电脑", "price": 8999.00, "description": "高性能游戏台式机", "created_at": "2025-11-03" }'8.2.2 批量添加文档curl -k -X POST "https://localhost:9200/_bulk" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ --data-binary @- << EOF {"index":{"_index":"products","_id":"2"}} {"name":"鼠标","price":99.00,"description":"无线办公鼠标","created_at":"2025-11-03"} {"index":{"_index":"products","_id":"3"}} {"name":"键盘","price":299.00,"description":"机械键盘","created_at":"2025-11-03"} EOF8.2.3 查询文档# 根据 ID 查询 curl -k -X GET "https://localhost:9200/products/_doc/1?pretty" \ -u elastic:你的密码 # 查询所有文档 curl -k -X GET "https://localhost:9200/products/_search?pretty" \ -u elastic:你的密码8.2.4 更新文档# 部分更新 curl -k -X POST "https://localhost:9200/products/_update/1" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "doc": { "price": 7999.00 } }' # 完整替换 curl -k -X PUT "https://localhost:9200/products/_doc/1" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "name": "台式电脑", "price": 7999.00, "description": "高性能游戏台式机（升级版）", "created_at": "2025-11-03" }'8.2.5 删除文档curl -k -X DELETE "https://localhost:9200/products/_doc/1" \ -u elastic:你的密码8.3 搜索查询8.3.1 全文搜索curl -k -X GET "https://localhost:9200/products/_search?pretty" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "query": { "match": { "name": "电脑" } } }'8.3.2 精确匹配curl -k -X GET "https://localhost:9200/products/_search?pretty" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "query": { "term": { "price": 5999.00 } } }'8.3.3 范围查询curl -k -X GET "https://localhost:9200/products/_search?pretty" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "query": { "range": { "price": { "gte": 100, "lte": 1000 } } } }'8.3.4 组合查询curl -k -X GET "https://localhost:9200/products/_search?pretty" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "query": { "bool": { "must": [ { "match": { "description": "办公" }} ], "filter": [ { "range": { "price": { "lte": 6000 }}} ] } } }'8.3.5 聚合查询# 统计平均价格 curl -k -X GET "https://localhost:9200/products/_search?pretty" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "size": 0, "aggs": { "avg_price": { "avg": { "field": "price" } } } }'9. 安全配置9.1 重置用户密码# 重置 elastic 用户密码 cd /usr/share/elasticsearch/bin # RPM/DEB 安装 # 或 cd /opt/elasticsearch/bin # tar.gz 安装 # 交互式重置 sudo ./elasticsearch-reset-password -u elastic # 自动生成密码 sudo ./elasticsearch-reset-password -u elastic -a # 手动设置密码 sudo ./elasticsearch-reset-password -u elastic -i9.2 创建新用户# 使用 API 创建用户 curl -k -X POST "https://localhost:9200/_security/user/myuser" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "password" : "mypassword", "roles" : [ "kibana_admin", "monitoring_user"], "full_name" : "My User", "email" : "myuser@example.com" }'9.3 配置 SSL/TLSElasticsearch 8.x 默认启用 TLS。如果需要禁用（仅开发环境）：# 编辑 elasticsearch.yml xpack.security.enabled: true xpack.security.http.ssl.enabled: false xpack.security.transport.ssl.enabled: false9.4 配置防火墙# CentOS/RHEL sudo firewall-cmd --permanent --add-port=9200/tcp sudo firewall-cmd --permanent --add-port=9300/tcp sudo firewall-cmd --reload # Ubuntu/Debian sudo ufw allow 9200/tcp sudo ufw allow 9300/tcp sudo ufw reload10. 性能优化10.1 JVM 参数优化# 编辑 jvm.options sudo vim /etc/elasticsearch/jvm.options添加以下配置：# GC 配置 -XX:+UseG1GC -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 # 堆转储配置（OOM 时） -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/lib/elasticsearch # GC 日志 -Xlog:gc*,gc+age=trace,safepoint:file=/var/log/elasticsearch/gc.log:utctime,pid,tags:filecount=32,filesize=64m10.2 索引优化# 调整刷新间隔 curl -k -X PUT "https://localhost:9200/products/_settings" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "index": { "refresh_interval": "30s" } }' # 增加批量处理大小 curl -k -X PUT "https://localhost:9200/_cluster/settings" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "persistent": { "http.max_content_length": "500mb" } }'10.3 磁盘优化# 在 elasticsearch.yml 中配置 index.merge.scheduler.max_thread_count: 1 # 使用 SSD 时 index.store.type: niofs10.4 查询缓存# 在 elasticsearch.yml 中配置 indices.queries.cache.size: 10% indices.requests.cache.size: 2%11. 常见问题与解决方案11.1 服务启动失败问题：max virtual memory areas vm.max_map_count is too low解决方案：sudo sysctl -w vm.max_map_count=262144 echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf问题：max file descriptors too low解决方案：# 编辑 limits.conf sudo vim /etc/security/limits.conf # 添加 elasticsearch soft nofile 65535 elasticsearch hard nofile 65535 # 重新登录 elasticsearch 用户11.2 内存不足问题：OutOfMemoryError解决方案：# 1. 增加堆内存（不超过 32GB） sudo vim /etc/elasticsearch/jvm.options -Xms8g -Xmx8g # 2. 减少内存使用 curl -k -X PUT "https://localhost:9200/_cluster/settings" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "persistent": { "indices.breaker.total.limit": "70%" } }' # 3. 重启服务 sudo systemctl restart elasticsearch11.3 磁盘空间不足问题：Disk watermark exceeded解决方案：# 1. 清理不需要的索引 curl -k -X DELETE "https://localhost:9200/old_index_*" \ -u elastic:你的密码 # 2. 调整水位线（临时） curl -k -X PUT "https://localhost:9200/_cluster/settings" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "transient": { "cluster.routing.allocation.disk.watermark.low": "90%", "cluster.routing.allocation.disk.watermark.high": "95%", "cluster.routing.allocation.disk.watermark.flood_stage": "97%" } }' # 3. 释放磁盘空间 sudo du -sh /var/lib/elasticsearch/*11.4 集群状态为 Yellow问题：副本分片未分配解决方案：# 单节点模式：设置副本数为 0 curl -k -X PUT "https://localhost:9200/_settings" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "index": { "number_of_replicas": 0 } }'11.5 无法连接到 Elasticsearch问题：Connection refused解决方案：# 1. 检查服务状态 sudo systemctl status elasticsearch # 2. 检查端口监听 sudo netstat -tlnp | grep 9200 # 3. 检查防火墙 sudo firewall-cmd --list-all # 4. 检查日志 sudo tail -f /var/log/elasticsearch/*.log # 5. 检查网络配置 grep "network.host" /etc/elasticsearch/elasticsearch.yml11.6 认证失败问题：Authentication failed解决方案：# 重置密码 cd /usr/share/elasticsearch/bin sudo ./elasticsearch-reset-password -u elastic -i # 或者禁用安全功能（仅开发环境） echo "xpack.security.enabled: false" | sudo tee -a /etc/elasticsearch/elasticsearch.yml sudo systemctl restart elasticsearch11.7 2核2G 环境特有问题问题：频繁 OutOfMemory 错误解决方案：# 1. 降低 JVM 堆内存 sudo vim /etc/elasticsearch/jvm.options -Xms512m -Xmx1g # 2. 限制查询结果大小 curl -k -X PUT "https://localhost:9200/_cluster/settings" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "persistent": { "search.max_buckets": 10000, "indices.query.bool.max_clause_count": 1024 } }' # 3. 减少并发 curl -k -X PUT "https://localhost:9200/_cluster/settings" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "transient": { "thread_pool.write.queue_size": 100, "thread_pool.search.queue_size": 300 } }'问题：启动缓慢或卡住解决方案：# 1. 临时禁用 Swap sudo swapoff -a # 2. 减少启动超时 sudo vim /etc/systemd/system/elasticsearch.service.d/override.conf [Service] TimeoutStartSec=300 # 3. 简化配置，移除非必要功能 sudo vim /etc/elasticsearch/elasticsearch.yml # 禁用 ML、监控等功能 xpack.ml.enabled: false xpack.monitoring.collection.enabled: false问题：查询响应慢解决方案：# 1. 增加索引刷新间隔 curl -k -X PUT "https://localhost:9200/your_index/_settings" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "index": { "refresh_interval": "60s" } }' # 2. 限制返回字段 curl -k -X GET "https://localhost:9200/your_index/_search" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "query": {...}, "_source": ["field1", "field2"], "size": 10 }' # 3. 使用过滤而不是查询（filter 有缓存） curl -k -X GET "https://localhost:9200/your_index/_search" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "query": { "bool": { "filter": [ {"term": {"status": "active"}} ] } } }'💡 2核2G 环境使用建议✅ 适合场景：开发、测试、小规模应用（<10GB数据）✅ 索引配置：1个分片，0个副本✅ 数据量：建议不超过 10GB✅ 并发量：建议不超过 10 QPS⚠️ 不适合：生产环境、大数据量、高并发场景12. 备份与恢复12.1 快照仓库配置12.1.1 创建快照目录sudo mkdir -p /opt/elasticsearch/backup sudo chown -R elasticsearch:elasticsearch /opt/elasticsearch/backup12.1.2 配置快照路径# 编辑 elasticsearch.yml sudo vim /etc/elasticsearch/elasticsearch.yml # 添加 path.repo: ["/opt/elasticsearch/backup"] # 重启服务 sudo systemctl restart elasticsearch12.1.3 注册快照仓库curl -k -X PUT "https://localhost:9200/_snapshot/my_backup" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "type": "fs", "settings": { "location": "/opt/elasticsearch/backup" } }'12.2 创建快照12.2.1 备份所有索引curl -k -X PUT "https://localhost:9200/_snapshot/my_backup/snapshot_1?wait_for_completion=true" \ -u elastic:你的密码12.2.2 备份特定索引curl -k -X PUT "https://localhost:9200/_snapshot/my_backup/snapshot_2" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "indices": "products,users", "ignore_unavailable": true, "include_global_state": false }'12.2.3 查看快照状态# 查看所有快照 curl -k -X GET "https://localhost:9200/_snapshot/my_backup/_all?pretty" \ -u elastic:你的密码 # 查看特定快照 curl -k -X GET "https://localhost:9200/_snapshot/my_backup/snapshot_1?pretty" \ -u elastic:你的密码12.3 恢复快照12.3.1 恢复所有索引curl -k -X POST "https://localhost:9200/_snapshot/my_backup/snapshot_1/_restore" \ -u elastic:你的密码12.3.2 恢复特定索引curl -k -X POST "https://localhost:9200/_snapshot/my_backup/snapshot_1/_restore" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "indices": "products", "ignore_unavailable": true, "include_global_state": false, "rename_pattern": "products", "rename_replacement": "products_restored" }'12.4 定期备份脚本创建自动备份脚本：sudo vim /usr/local/bin/es-backup.sh脚本内容：#!/bin/bash # Elasticsearch 配置 ES_HOST="https://localhost:9200" ES_USER="elastic" ES_PASS="你的密码" REPO_NAME="my_backup" DATE=$(date +%Y%m%d_%H%M%S) SNAPSHOT_NAME="snapshot_${DATE}" # 创建快照 echo "开始创建快照: ${SNAPSHOT_NAME}" curl -k -X PUT "${ES_HOST}/_snapshot/${REPO_NAME}/${SNAPSHOT_NAME}?wait_for_completion=true" \ -u ${ES_USER}:${ES_PASS} \ -H 'Content-Type: application/json' \ -d '{ "ignore_unavailable": true, "include_global_state": false }' # 检查结果 if [ $? -eq 0 ]; then echo "快照创建成功: ${SNAPSHOT_NAME}" # 删除 7 天前的快照 OLD_DATE=$(date -d "7 days ago" +%Y%m%d) echo "清理旧快照..." curl -k -X DELETE "${ES_HOST}/_snapshot/${REPO_NAME}/snapshot_${OLD_DATE}_*" \ -u ${ES_USER}:${ES_PASS} else echo "快照创建失败" exit 1 fi设置权限并添加到 crontab：sudo chmod +x /usr/local/bin/es-backup.sh # 添加定时任务（每天凌晨 2 点执行） sudo crontab -e 0 2 * * * /usr/local/bin/es-backup.sh >> /var/log/es-backup.log 2>&113. 监控与维护13.1 集群监控13.1.1 查看集群状态# 集群健康 curl -k -u elastic:你的密码 "https://localhost:9200/_cluster/health?pretty" # 节点信息 curl -k -u elastic:你的密码 "https://localhost:9200/_cat/nodes?v" # 索引状态 curl -k -u elastic:你的密码 "https://localhost:9200/_cat/indices?v&s=store.size:desc" # 分片分配 curl -k -u elastic:你的密码 "https://localhost:9200/_cat/shards?v"13.1.2 查看资源使用# 线程池 curl -k -u elastic:你的密码 "https://localhost:9200/_cat/thread_pool?v" # 内存使用 curl -k -u elastic:你的密码 "https://localhost:9200/_cat/nodes?v&h=name,heap.percent,ram.percent,cpu" # JVM 信息 curl -k -u elastic:你的密码 "https://localhost:9200/_nodes/stats/jvm?pretty"13.2 性能指标# 慢查询日志配置 curl -k -X PUT "https://localhost:9200/products/_settings" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "index.search.slowlog.threshold.query.warn": "10s", "index.search.slowlog.threshold.query.info": "5s", "index.search.slowlog.threshold.fetch.warn": "1s", "index.indexing.slowlog.threshold.index.warn": "10s" }'13.3 日常维护任务13.3.1 清理旧索引# 删除 30 天前的日志索引 curl -k -X DELETE "https://localhost:9200/logs-2025.09.*" \ -u elastic:你的密码13.3.2 优化索引# 强制合并索引（减少段数量） curl -k -X POST "https://localhost:9200/products/_forcemerge?max_num_segments=1" \ -u elastic:你的密码13.3.3 清理缓存# 清理所有缓存 curl -k -X POST "https://localhost:9200/_cache/clear" \ -u elastic:你的密码14. 升级 Elasticsearch14.1 升级前准备# 1. 备份配置文件 sudo cp -r /etc/elasticsearch /etc/elasticsearch.backup # 2. 创建快照 curl -k -X PUT "https://localhost:9200/_snapshot/my_backup/pre_upgrade_snapshot?wait_for_completion=true" \ -u elastic:你的密码 # 3. 禁用分片分配 curl -k -X PUT "https://localhost:9200/_cluster/settings" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "persistent": { "cluster.routing.allocation.enable": "primaries" } }' # 4. 停止索引并执行同步刷新 curl -k -X POST "https://localhost:9200/_flush/synced" \ -u elastic:你的密码14.2 执行升级# CentOS/RHEL sudo yum update elasticsearch -y # Ubuntu/Debian sudo apt-get update sudo apt-get upgrade elasticsearch -y # 重启服务 sudo systemctl restart elasticsearch14.3 升级后操作# 1. 等待节点加入集群 sleep 30 # 2. 重新启用分片分配 curl -k -X PUT "https://localhost:9200/_cluster/settings" \ -u elastic:你的密码 \ -H 'Content-Type: application/json' \ -d '{ "persistent": { "cluster.routing.allocation.enable": null } }' # 3. 验证集群健康 curl -k -u elastic:你的密码 "https://localhost:9200/_cluster/health?pretty"15. 附录15.1 常用端口端口用途9200HTTP REST API9300节点间通信（Transport）15.2 重要文件路径类型RPM/DEB 路径tar.gz 路径主目录/usr/share/elasticsearch/opt/elasticsearch配置文件/etc/elasticsearch/opt/elasticsearch/config数据目录/var/lib/elasticsearch/opt/elasticsearch/data日志目录/var/log/elasticsearch/opt/elasticsearch/logs插件目录/usr/share/elasticsearch/plugins/opt/elasticsearch/plugins证书目录/etc/elasticsearch/certs/opt/elasticsearch/config/certs15.3 环境变量# 添加到 /etc/profile 或 ~/.bashrc export ES_HOME=/usr/share/elasticsearch export ES_PATH_CONF=/etc/elasticsearch export PATH=$PATH:$ES_HOME/bin15.4 有用的资源官方文档：https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html中文社区：https://elasticsearch.cn/GitHub：https://github.com/elastic/elasticsearch讨论论坛：https://discuss.elastic.co/15.5 快速命令参考# 查看所有索引 curl -k -u elastic:密码 "https://localhost:9200/_cat/indices?v" # 查看集群健康 curl -k -u elastic:密码 "https://localhost:9200/_cluster/health?pretty" # 查看节点信息 curl -k -u elastic:密码 "https://localhost:9200/_cat/nodes?v" # 查看分片分配 curl -k -u elastic:密码 "https://localhost:9200/_cat/shards?v" # 查看正在执行的任务 curl -k -u elastic:密码 "https://localhost:9200/_tasks?pretty" # 查看插件列表 curl -k -u elastic:密码 "https://localhost:9200/_cat/plugins?v" # 查看索引模板 curl -k -u elastic:密码 "https://localhost:9200/_cat/templates?v" # 查看别名 curl -k -u elastic:密码 "https://localhost:9200/_cat/aliases?v"结语本文档详细介绍了 Elasticsearch 在 Linux 服务器上的完整安装和使用流程。从环境准备、安装配置、基本使用到性能优化和故障排查，涵盖了日常运维中的常见场景。在生产环境中使用 Elasticsearch 时，建议：合理配置集群，至少 3 个主节点定期备份重要数据监控集群健康状态和性能指标根据业务需求调整索引策略保持软件版本更新
RestHighLevelClient操作查询文档查询操作基本步骤//注入依赖 @Autowired private RestHighLevelClient restHighLevelClient; //1.创建查询索引对象 SearchRequest request = new SearchRequest("索引库名"); //2.创建构生成器对象 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); sourceBuilder.query(QueryBuilders qbs); //可以直接写成 => request.source().query(QueryBuilders qbs); //不创建对象 //3.传入生成器 request.source(sourceBuilder); //4.发送请求 SearchResponse response = client.search(request, RequestOptions.DEFAULT); //5.解析响应数据 handleResponse(response);批量同步 //数据库同步索引库-批量操作 @Test void testBulkNewRequest() throws IOException { //分页打包添加 批量导入文档 int page = 1; int size = 100; Page<Hotel> hotelPage = hotelService.page(new Page<>(page, size)); for (long i = 1; i <= hotelPage.getPages(); i++) { Page<Hotel> hotelData = hotelService.page(new Page<>(i, size)); BulkRequest bulkRequest = new BulkRequest(); for (Hotel hotel : hotelData.getRecords()) { HotelDoc hotelDoc = new HotelDoc(hotel); String hotelString = JSONObject.toJSONString(hotelDoc); bulkRequest.add(new IndexRequest("hotel") .id(hotelDoc.getId().toString()) .source(hotelString, XContentType.JSON)); } client.bulk(bulkRequest, RequestOptions.DEFAULT); } }文档的增删改查操作class HotelDocumentTest { @Autowired private RestHighLevelClient client; @Autowired private IHotelService hotelService; /** * 文档的增删改查操作 * * @throws IOException io */ @Test void testAddDoc() throws IOException { //1.查询数据库hotel数据 Hotel hotel = hotelService.getById(61083); //2.转换为HotelDoc HotelDoc hotelDoc = new HotelDoc(hotel); //3.转换成json String jsonString = JSONObject.toJSONString(hotelDoc); //4.准备request IndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId().toString()); //5.这是发送的文档 request.source(jsonString, XContentType.JSON); client.index(request, RequestOptions.DEFAULT); } @Test void testGetDoc() throws IOException { //1.准备Request GetRequest request = new GetRequest("hotel").id("61083"); //2.发送请求 GetResponse response = client.get(request, RequestOptions.DEFAULT); //3.解析响应 String source = response.getSourceAsString(); //json转换成对象 HotelDoc hotelDoc = JSON.parseObject(source, HotelDoc.class); System.out.println(hotelDoc); } @Test void testDeleteDoc() throws IOException { DeleteRequest request = new DeleteRequest("hotel", "s1bhYYsBHGmKNOlBr0L6"); client.delete(request, RequestOptions.DEFAULT); } @Test void testUpdateDoc() throws IOException { UpdateRequest request = new UpdateRequest("hotel", "61083"); request.doc( "price", "999" ); client.update(request, RequestOptions.DEFAULT); }完全匹配查询 @Test void testMatchAll() throws IOException { SearchRequest request = new SearchRequest("hotel"); //查询所有数据 /* GET /_search { "query": { "match_all": {} } } */ request.source().query(QueryBuilders.matchAllQuery()); //查询单字段 /* GET /index_name/_search { "query": { "match": { "name": "如家" } } } */ request.source().query(QueryBuilders.matchQuery("name", "如家")); //查询多个字段 /* GET /hotel/_search { "query": { "multi_match": { "query": "如家", "fields": ["name","brand"] } } } */ request.source().query(QueryBuilders.multiMatchQuery("如家", "name", "brand")); //发送请求 SearchResponse response = client.search(request, RequestOptions.DEFAULT); //解析响应 handleResponse(response); }精确查询 @Test void testExactQuery() throws IOException { SearchRequest request = new SearchRequest("hotel"); //查询所有数据 准备DSL //精确查询 /* GET /hotel/_search { "query": { "term": { "city": { "value": "北京" } } } } */ request.source().query(QueryBuilders.termQuery("city", "北京")); //发送请求 SearchResponse response = client.search(request, RequestOptions.DEFAULT); //解析响应 handleResponse(response); }布尔查询 @Test void testBooleanQueries() throws IOException { SearchRequest request = new SearchRequest("hotel"); //查询所有数据 //布尔查询 /* GET /hotel/_search { "query": { "bool": { "must": [ { "multi_match": { "query": "如家", "fields": [ "name" ] } } ], "must_not": [ { "range": { "price": { "gte": 0, "lte": 400 } } } ], "filter": [ { "geo_distance": { "distance": "10km", "location": "39.909187,116.397455" } } ] } } } */ request.source().query(QueryBuilders.boolQuery() .must(QueryBuilders.multiMatchQuery("如家", "name")) .mustNot(QueryBuilders.rangeQuery("price").gte(0).lte(400)) .filter(QueryBuilders.geoDistanceQuery("location").distance("10km").point(39.909187, 116.397455))); //发送请求 SearchResponse response = client.search(request, RequestOptions.DEFAULT); //解析响应 handleResponse(response); }分页排序 @Test void testPage() throws IOException { SearchRequest request = new SearchRequest("hotel"); //查询所有数据 准备DSL //分页 排序 /* GET /hotel/_search { "query": { "match_all": {} }, "from": 0, "size": 5, "sort": [ { "price": { "order": "desc" } } ] } */ request.source() .query(QueryBuilders.matchAllQuery()) .from(1) .size(10) .sort("price", SortOrder.DESC); //发送请求 SearchResponse response = client.search(request, RequestOptions.DEFAULT); //解析响应 handleResponse(response); }关键字高亮处理 @Test void testHighlight() throws IOException { SearchRequest request = new SearchRequest("hotel"); //查询所有数据 准备DSL //高亮 /* #如果要对非搜索字段高亮，则需要添加一个属性：required_field_match=false GET /hotel/_search { "query": { "match": { "all": "如家" } }, "highlight": { "fields": { "name": { "require_field_match": "false" } } } } #// 查询条件，高亮一定要使用全文检索查询 GET /hotel/_search { "query": { "match": { "brand": "如家" } }, "highlight": { "fields": { "brand": { "pre_tags": "", "post_tags": "" } } } } */ request.source() .query(QueryBuilders.matchQuery("brand", "如家")) .highlighter(new HighlightBuilder() .field("brand") .preTags("") .postTags("")); //发送请求 SearchResponse response = client.search(request, RequestOptions.DEFAULT); //解析响应 handleResponseTag(response); }响应数据统一处理 /** * 处理响应数据方法 * * @param response 响应数据 */ private void handleResponse(SearchResponse response) { long value = response.getHits().getTotalHits().value; System.out.println("总共" + value + "条记录"); for (SearchHit hit : response.getHits().getHits()) { String source = hit.getSourceAsString(); //字符串反序列化成对象 HotelDoc hotelDoc = JSON.parseObject(source, HotelDoc.class); System.out.println(hotelDoc); } } /** * 处理高亮显示数据响应 * * @param response 响应数据 */ private void handleResponseTag(SearchResponse response) { // 4.解析响应 SearchHits searchHits = response.getHits(); // 4.1.获取总条数 long total = searchHits.getTotalHits().value; System.out.println("共搜索到" + total + "条数据"); // 4.2.文档数组 SearchHit[] hits = searchHits.getHits(); // 4.3.遍历 for (SearchHit hit : hits) { // 获取文档source String json = hit.getSourceAsString(); // 反序列化 HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class); // 获取高亮结果 Map<String, HighlightField> highlightFields = hit.getHighlightFields(); if (!CollectionUtils.isEmpty(highlightFields)) { // 根据字段名获取高亮结果 HighlightField highlightField = highlightFields.get("brand"); if (highlightField != null) { // 获取高亮值 String brand = highlightField.getFragments()[0].string(); // 覆盖非高亮结果 hotelDoc.setBrand(brand); } } System.out.println(hotelDoc); } } }
DSL查询文档查询所有：查询出所有数据，一般测试用。例如：match_all全文检索（full text）查询：利用分词器对用户输入内容分词，然后去倒排索引库中匹配。例如：match_querymulti_match_query精确查询：根据精确词条值查找数据，一般是查找keyword、数值、日期、boolean等类型字段。例如：idsrangeterm地理（geo）查询：根据经纬度查询。例如：geo_distancegeo_bounding_box复合（compound）查询：复合查询可以将上述各种查询条件组合起来，合并查询条件。例如：boolfunction_score1.全文检索查询#match查询 //搜索字段越多，对查询性能影响越大，因此建议采用copy_to，然后单字段查询的方式比较好 GET /hotel/_search { "query": { "match": { "all":"上海外滩" } } } #multi_match查询 GET /hotel/_search { "query": { "multi_match": { "query": "如家", "fields": ["name","business"] } } }2.精准查询2.1term查询因为精确查询的字段搜是不分词的字段，因此查询的条件也必须是不分词的词条。查询时，用户输入的内容跟自动值完全匹配时才认为符合条件。如果用户输入的内容过多，反而搜索不到数据。//term 精准查询 GET /hotel/_search { "query": { "term": { "name": { "value": "上海" } } } }2.22.range查询范围查询，一般应用在对数值类型做范围过滤的时候。比如做价格范围过滤//range 范围查询 GET /hotel/_search { "query": { "range": { "price": { "gte": 100, "lte": 200 } } } }3.地理坐标查询所谓的地理坐标查询，其实就是根据经纬度查询官方文档：https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-queries.html常见的使用场景包括：携程：搜索我附近的酒店滴滴：搜索我附近的出租车微信：搜索我附近的人#geo_bounding_box矩形查询 GET /hotel/_search { "query": { "geo_bounding_box":{ "location":{ "top_left":{ "lat":31.1, "lon":121.5 }, "bottom_right":{ "lat":30.9, "lon":121.7 } } } } }#geo_distance 距离查询 GET /hotel/_search { "query": { "geo_distance":{ "distance":"100km", "location":"39.909187,116.397455" //天安门 } } }4.算分函数查询function score 查询中包含四部分内容：原始查询条件：query部分，基于这个条件搜索文档，并且基于BM25算法给文档打分，原始算分（query score)过滤条件：filter部分，符合该条件的文档才会重新算分算分函数：符合filter条件的文档要根据这个函数做运算，得到的函数算分（function score），有四种函数weight：函数结果是常量field_value_factor：以文档中的某个字段值作为函数结果random_score：以随机数作为函数结果script_score：自定义算分函数算法运算模式：算分函数的结果、原始查询的相关性算分，两者之间的运算方式，包括：multiply：相乘replace：用function score替换query score其它，例如：sum、avg、max、min#算分查询 GET /hotel/_search { "query": { "function_score": { "query": { "match": { "all": "外滩" } }, "functions": [ { "filter": { "term": { "brand": "如家" } }, "weight": 10 //加权重 } ], "boost_mode": "sum" } } }5.布尔查询布尔查询是一个或多个查询子句的组合，每一个子句就是一个子查询。子查询的组合方式有：must：必须匹配每个子查询，类似“与”should：选择性匹配子查询，类似“或”must_not：必须不匹配，不参与算分，类似“非”filter：必须匹配，不参与算分示例需求：搜索名字包含“如家”，价格不高于400，在坐标39.909187,116.397455周围10km范围内的酒店。分析：名称搜索，属于全文检索查询，应该参与算分。放到must中价格不高于400，用range查询，属于过滤条件，不参与算分。放到must_not中周围10km范围内，用geo_distance查询，属于过滤条件，不参与算分。放到filter中#布尔查询 GET /hotel/_search { "query": { "bool": { "must": [ { "multi_match": { "query": "如家", "fields": [ "name" ] } } ], "must_not": [ { "range": { "price": { "gte": 0, "lte": 400 } } } ], "filter": [ { "geo_distance": { "distance": "10km", "location": "39.909187,116.397455" } } ] } } }搜索结果操作搜索结果排序sortGET /hotel/_search{ "query": {"match_all": { }}, "sort": [{ "price": { "order": "desc" } }]}地理坐标排序GET /hotel/_search{ "query": {"match_all": {}}, "sort": [{ "_geo_distance": { "order": "desc", "location": { "lat": 31.208553, "lon": 121.518552 }, "unit": "km" } }]}分页排序GET /hotel/_search{ "query": {"match_all": {}}, "from": 0, "size": 5, "sort": [{ "price": { "order": "desc" } }]}高亮如果要对非搜索字段高亮，则需要添加一个属性：required_field_match=falseGET /hotel/_search{ "query": {"match": { "all": "如家" }}, "highlight": {"fields": { "name": { "require_field_match": "false" } }}}// 查询条件，高亮一定要使用全文检索查询GET /hotel/_search{ "query": {"match": { "brand": "如家" }}, "highlight": {"fields": { "brand": { "pre_tags": "", "post_tags": "" } }}}
RestClient操作文档初始化RestClient在elasticsearch提供的API中，与elasticsearch一切交互都封装在一个名为RestHighLevelClient的类中，必须先完成这个对象的初始化，建立与elasticsearch的连接。分为三步：1）引入es的RestHighLevelClient依赖：<dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> </dependency>2）因为SpringBoot默认的ES可能版本不一致，所以我们需要覆盖默认的ES版本：<properties> <java.version>1.8</java.version> <elasticsearch.version>7.12.1</elasticsearch.version> </properties>3）初始化RestHighLevelClient：初始化的代码如下：//可以使用配置类交给ioc @Configuration public class ESConfig { @Bean public RestHighLevelClient restHighLevelClient() { return new RestHighLevelClient( RestClient.builder( new HttpHost("00.0xx.x0x.xxx", 9200, "http") )); } } 索引库相关操作@SpringBootTest class HotelIndexTest { @Autowired private RestHighLevelClient client; //创建索引库 @Test void testCreateIndex() throws Exception { // 1.准备Request PUT /hotel CreateIndexRequest request = new CreateIndexRequest("hotel"); // 2.准备请求参数 request.source(MAPPING_TEMPLATE, XContentType.JSON); // 3.发送请求 client.indices().create(request, RequestOptions.DEFAULT); } //删除索引库 @Test void testDeleteIndex() throws IOException { // 1.准备Request DeleteIndexRequest request = new DeleteIndexRequest("hotel"); // 2.判断存不存在 GetIndexRequest indexRequest = new GetIndexRequest("hotel"); boolean exists = client.indices().exists(indexRequest, RequestOptions.DEFAULT); if (!exists) { System.out.println("不存在哦！"); return; } // 3.发送请求 client.indices().delete(request, RequestOptions.DEFAULT); } //判断是否存在 @Test void testGetIndex() throws IOException { GetIndexRequest request = new GetIndexRequest("hotel"); boolean exists = client.indices().exists(request, RequestOptions.DEFAULT); System.out.println(exists ? "存在" : "不存在"); } }Document文档操作@SpringBootTest class HotelDocumentTest { @Autowired private RestHighLevelClient client; @Autowired private IHotelService hotelService; @Test void testAddDoc() throws IOException { //1.查询数据库hotel数据 Hotel hotel = hotelService.getById(61083); //2.转换为HotelDoc HotelDoc hotelDoc = new HotelDoc(hotel); //3.转换成json String jsonString = JSONObject.toJSONString(hotelDoc); //4.准备request IndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId().toString()); //5.这是发送的文档 request.source(jsonString, XContentType.JSON); client.index(request, RequestOptions.DEFAULT); } @Test void testGetDoc() throws IOException { //1.准备Request GetRequest request = new GetRequest("hotel").id("61083"); //2.发送请求 GetResponse response = client.get(request, RequestOptions.DEFAULT); //3.解析响应 String source = response.getSourceAsString(); //json转换成对象 HotelDoc hotelDoc = JSON.parseObject(source, HotelDoc.class); System.out.println(hotelDoc); } @Test void testDeleteDoc() throws IOException { DeleteRequest request = new DeleteRequest("hotel", "61083"); client.delete(request, RequestOptions.DEFAULT); } @Test void testUpdateDoc() throws IOException { UpdateRequest request = new UpdateRequest("hotel", "61083"); request.doc( "price", "999" ); client.update(request, RequestOptions.DEFAULT); } @Test void testBulkNewRequest() throws IOException { //分页打包添加 int page = 1; int size = 100; Page<Hotel> hotelPage = hotelService.page(new Page<>(page, size)); for (long i = 1; i <= hotelPage.getPages(); i++) { Page<Hotel> hotelData = hotelService.page(new Page<>(i, size)); BulkRequest bulkRequest = new BulkRequest(); for (Hotel hotel : hotelData.getRecords()) { HotelDoc hotelDoc = new HotelDoc(hotel); String hotelString = JSONObject.toJSONString(hotelDoc); bulkRequest.add(new IndexRequest("hotel") .id(hotelDoc.getId().toString()) .source(hotelString, XContentType.JSON)); } client.bulk(bulkRequest, RequestOptions.DEFAULT); } } }
ElasticSearch(ES)索引库与文档的创建和操作索引库操作有哪些？创建索引库：PUT /索引库名查询索引库：GET /索引库名删除索引库：DELETE /索引库名添加字段：PUT /索引库名/_mapping##创建索引库 PUT /test { "mappings": { "properties": { "info": { "type": "text", "analyzer": "ik_smart" }, "email": { "type": "keyword", "index": false }, "name":{ "type": "object", "properties": { "firstName":{ "type":"keyword" }, "lastName":{ "type":"keyword" } } } } } } #查询索引库 GET /test/_mapping GET /test/_search #修改（新增）索引库字段 PUT /test/_mapping { "properties":{ "age":{ "type":"integer" }, "weight":{ "type":"float" }, "isMarried":{ "type":"boolean" }, "score":{ "type":"float" } } } #删除数据库 DELETE /test文档操作有哪些？创建文档：POST /{索引库名}/_doc/文档id { json文档 }查询文档：GET /{索引库名}/_doc/文档id删除文档：DELETE /{索引库名}/_doc/文档id修改文档：全量修改：PUT /{索引库名}/_doc/文档id { json文档 }增量修改：POST /{索引库名}/_update/文档id { "doc": {字段}}## 文档操作 #新增文档 POST /test/_doc/1 { "info":"我是大帅哥", "email":"admin@oalo.cn", "name":{ "firstName":"哥", "lastName":"帅" }, "age": "18", "weight":"120", "score":[99,99,100], "isMarried":false } #查询所有 GET /test/_search #根据id查询 GET /test/_doc/1 #根据id进行删除文档 DELETE /test/_doc/1 # 修改文档 #1.全量修改 PUT /test/_doc/1 { "info":"我依旧是大帅哥", "email":"admin@oalo.cn", "name":{ "firstName":"比", "lastName":"帅" }, "age": "18", "weight":"110", "score":[99,99,100], "isMarried":false } #2.增量修改 POST /test/_update/1 { "doc": { "email":"521@oalo.cn" } }
1）引入es的RestHighLevelClient依赖：<dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> </dependency>2）因为SpringBoot默认的ES版本是7.6.2，所以我们需要覆盖默认的ES版本：<properties> <java.version>1.8</java.version> <elasticsearch.version>7.12.1</elasticsearch.version> </properties>3）初始化RestHighLevelClient：初始化的代码如下：@Getter @Setter @Configuration @ConfigurationProperties(prefix = "elasticsearch") public class ElasticSearchConfig { private String host; private int port; @Bean public RestHighLevelClient client(){ System.out.println(host); System.out.println(port); return new RestHighLevelClient(RestClient.builder( new HttpHost( host, port, "http" ) )); } }#自定义elasticsearch连接配置 elasticsearch: host: 192.168.200.130 port: 9200