赞
踩
目录
七、ES SDK及增删改查Demo
- PUT test001
- {
- "settings": {
- "number_of_shards": 5,
- "number_of_replicas": 1
- },
- "mappings": {
- "properties": {
- "id": {
- "type": "long"
- },
- "name": {
- "type": "text",
- "analyzer": "ik_max_word"
- },
- "age": {
- "type": "integer"
- }
- }
- }
- }
注:由于elasticsearch各版本差异较大,所以在调研及给出具体的方案前我们需要确定使用的es版本
通过大量资料搜索对比了对各个版本差异,最终选择7.10比较稳定的版本来使用。 es从5.x、6.x、7.x、8.x设计及sdk差异都比较大,5和6版本比较老了,与现在spring boot 2.x版本集成存在问题,8.x比较新才出一两年也有比较多的license限制,所以最终选择了7.10版本。
类型\版本 | 6.x | 7.x | 8.x | 建议 |
Licence | Apache 2.0 |
7.0 ~ 7.10 Apache 2.0
7.11++ SSPL
|
SSPL
|
建议选择更友好的Apache2.0版本,sspl对于在云上想要让ES as a Service,将会面临es厂商的限制
|
云厂商支持程度
| 腾讯、阿里云均支持, 华为不支持 |
腾讯云最高版 7.10.x
阿里云7.10.x,7.16.x
华为云7.6.x, 7.10.x
|
均不支持
|
各云厂商也主要在推广7.x版本,稳定性及占用率更高,建议选择7.x中的7.10.0版本
|
发版时间
| 初版2016 |
2019年
|
2021年底
|
建议选择
7.x版本,经历将近4年,稳定性已经经过验证,6.x和8.x一个太老一个太新
|
特性差异
| / | 集群配置简化,master选举进行了优化, 能够避免集群脑裂问题; 索引创建已经去除了type,更加简化; 索引查询算法升级,查询性能有优化; 提供安全策略; Kibana更轻量化,更易用; |
ES API进行了升级方便后续升级使用;
更加安全,es默认开启了一些安全功能;
新的搜索API 特性,比如支持NLP等;
|
7.x基本也能满足目前需求,稳定性也更有保障
|
2.1 ~ 2.2版本对6.x支持 |
2.3 ~ 2.7版本对7.x支持
| / |
基于目前应用中使用的spring boot版本,只能选择
7.x版本
|
客户端 | 适用版本 | 优点 | 缺点 | 建议 |
TransportClient | 5.x 6.x | 启动速度快,轻量级,可创建极多连接,与应用程序解耦;推荐使用原生的,ES本身就很简单,灵活性很高 | 分发或查询数据速度较慢,不能获取指定节点数据,高版本已经废弃 | 不建议使用 |
JestClient | 5.x 6.x 7.x | 提供Restful API, 原生ES API不具备;若ES集群使用不同的ES版本,使用原生ES API会有问题,而Jest不会;更安全(可以在Http层添加安全处理);JestClient是ElasticSearch的Java HTTP Rest客户端; JestClient填补了 ElasticSearch缺少HttpRest接口客户端的空白; JestClient可以跨版本 | 18年已经停止更新,7.x、8.x版本兼容性存疑 | 不建议使用 |
RestClient low-level-rest-client | 5.0++ | 基于Http Client 进行的简单封装,RestClient可以跨版本,支持到目前8.x所有版本。 | HttpClient和Jsoup都不直接支持发送DELETE方法带参数的请求(官方高版本已经放弃使用)。使用成本较高 | 不推荐 |
high-level-rest-client | 7.2.0 - 7.16.x | 官方基于RestClient进行的封装,提供一系列API方便对ES的使用 | 在7.17版本后官方又废弃了 | 7部分版本推荐使用 |
New ElasticsearchClient | 7.17++ | 为最新官方提供的版本 | 较高版本es适用 | 8.x官方推荐使用 |
spring-boot-es-starter | 3.0++ | spring官方封装的ES api,使用起来相对简单,也spring兼容性也能保障,教程也比较多。 | 需要与使用的es版本进行匹配 | 推荐使用 |
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.yml,并添加以下配置(此时不要添加集群和证书配置)
- path.data: /opt/data
- path.logs: /opt/logs
-
- #http访问端口,程序或kibana使用
- http.port: 9200
-
- xpack.security.enabled: true
- xpack.security.transport.ssl.enabled: true
bin/elasticsearch-setup-passwords interactive
- #数据和日志存储路径
- path.data: /opt/data
- path.logs: /opt/logs
- #数据备份和恢复使用,可以一到多个目录
- path.repo: ["/opt/backup/es", "/opt/backup/es1"]
-
- #http访问端口,程序或kibana使用
- http.port: 9200
-
- #集群名称
- cluster.name: es001
- #节点名,每个节点名不能重复
- node.name: node1
-
- #是否可以参与选举主节点
- 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: ["xxx.xx.xx.xx:9300", "xx.xx.xx:9300", "xx.xx.xx: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.security.transport.ssl.enabled: true
- xpack.license.self_generated.type: basic
- xpack.security.transport.ssl.verification_mode: certificate
- xpack.security.transport.ssl.keystore.path: certs/elastic-certificates.p12
- xpack.security.transport.ssl.truststore.path: certs/elastic-certificates.p12
-
-
- #默认为1s,指定了节点互相ping的时间间隔。
- discovery.zen.fd.ping_interval: 1s
- #默认为30s,指定了节点发送ping信息后等待响应的时间,超过此时间则认为对方节点无响应。
- discovery.zen.fd.ping_timeout: 30s
- #ping失败后重试次数,超过此次数则认为对方节点已停止工作。
- discovery.zen.fd.ping_retries: 3
- -Xms6g
- -Xmx6g
- sudo vim /etc/sysctl.conf
-
- #添加参数
- vm.max_map_count = 262144
-
- #重新加载配置
- sysctl -p
curl -XGET -u elastic:elastic123 "http://127.0.0.1:9200/_cluster/health?pretty"
curl -XPUT -u elastic:elastic123 "http://127.0.0.1:9200/test-index"
curl -XGET -u elastic:elastic123 "http://localhost:9200/_cat/indices?pretty"
- PUT _cluster/settings
- {
- "persistent": {
- "action.auto_create_index": "false"
- }
- }
PUT _cluster/settings { "persistent": { "action.auto_create_index": "false" } }
- PUT _template/template_http_request_record
- {
- "index_patterns": [
- "*"
- ],
- "settings": {
- "number_of_shards": 5,
- "number_of_replicas": 1
- }
- }
合理设置分片意义
es是一个分式式的搜索引擎,ES中默认为每个索引创建5个分片,每个分片提供一个备份。如果分片过小,当索引数据量非常大的话,每个分片上的数据就会比较多,导致检索时候效率较低,反之分片过多各节点之间的数据同步会过多消耗集群资源、检索时多分片数据归并也会影响效率,所以需要有一些标准来设置合理的分片避免上述问题。
- 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 )
结论
集群能承受的分片数
单实例推荐最大分片数: (8G-2G-0.5G) * 20 = 110 个分片
依目前3个4C8G实例规格举例来说明:
单实例推荐最大分片数: (8G-2G-0.5G) * 20 = 110 个分片
2G留给操作系统及其它软件内存使用,0.5G是留给ES本身做计算所需的内存资源。
所以当前集群可以承载110 * 3 = 330 个分片,假如每个索引5个分片,整个集群可以容纳 330 / 5 = 66 个索引单个索引分片数
依上面经验来计算3个节点的集群,索引分片为5-9个 比较合适
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.10.0/elasticsearch-analysis-ik-7.10.0.zip
- POST _analyze
- {
- "analyzer": "ik_max_word",
- "text":"中国河南南阳"
- }
完整代码可以从github上下载
https://github.com/caizi12/my-elasticsearch-starter.git
代码说明
封装了易于使用的elasticsearch starter,使用时可以先把代码Deploy到私有仓库中,然后应用程序中依赖使用,如果没有私有仓库可以把代码copy到应用中使用。
Deploy到仓库后使用方式
- <dependency>
- <groupId>com.my.es</groupId>
- <artifactId>elasticsearch-starter</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </dependency>
- #es链接地址
- spring.elasticsearch.uris=http://localhost:9200
-
- #es账号密码,根据实际填写
- spring.elasticsearch.username=elastic
- spring.elasticsearch.password=123456
- #可省配置:连接es集群超时参数,默认毫秒
- spring.elasticsearch.connection-timeout=300
- spring.elasticsearch.read-timeout=300
-
-
- @SpringBootTest
- public class MyEsServiceTest {
- @Autowired
- private MyEsService myEsService;
-
- @Test
- public void delIndex() {
- boolean result = myEsService.deleteIndexIfExist(Student.class);
- Assert.assertTrue(result);
- }
-
- @Test
- public void delIndexDoc() {
- String result = myEsService.delIndexDoc("3007", Student.class);
- System.out.println("delIndexDoc:" + Student.class.getName());
- }
-
-
- @Test
- public void updateMapping() {
- boolean result = myEsService.updateIndexMapping(Student.class);
- Assert.assertTrue(result);
- }
-
-
- @Test
- public void updateIndexMapping() {
- boolean result = myEsService.updateIndexMapping(Shop.class);
- Assert.assertTrue(result);
- }
-
- @Test
- public void createIndex() {
- boolean exist = myEsService.existIndex(Student.class);
- boolean result = false;
- if (!exist) {
- result = myEsService.createIndexIfNotExist(Student.class);
- } else {
- System.out.println("index exist:" + Student.class.getName());
- }
- Assert.assertTrue(result);
- }
-
-
- @Test
- public void addIndexDoc() {
- Student student = new Student(1000, "张三", "测试索引添加", "哈哈", "三年二班刘", 10, new Date(), null);
- String documentId = myEsService.addIndexDoc(student);
- System.out.println("addIndexDoc result:" + documentId);
- Assert.assertNotNull(documentId);
- }
- }
ES SDK封装代码示例
接口定义
- package com.my.elasticsearch;
-
- import java.util.List;
-
- import javax.annotation.Nullable;
-
- import com.my.elasticsearch.model.MyEsSearchRequest;
- import org.elasticsearch.index.query.QueryBuilder;
- import org.springframework.data.domain.Pageable;
- import org.springframework.data.elasticsearch.core.IndexedObjectInformation;
- import org.springframework.data.elasticsearch.core.SearchHits;
- import org.springframework.data.elasticsearch.core.query.BulkOptions;
- import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
- import org.springframework.data.elasticsearch.core.query.UpdateResponse;
-
- /**
- * es服务接口,该接口提供对es的增删改查操作
- *
- * @authro nantian
- * @date 2022-10-08 15:19
- */
- public interface MyEsService {
- /**
- * 判断索引是否存在, 文档需标注@Document注解
- *
- * @param clazz
- * @return
- */
- boolean existIndex(Class<?> clazz);
-
- /**
- * 判断索引是否存在, 文档需标注@Document注解
- *
- * @param clazz
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- boolean existIndex(Class<?> clazz, boolean nonTenantMode);
-
- /**
- * 创建索引并设置mapping,setting信息
- * 文档需标注@Document注解、包含@Id注解,其它属性字段需要添加@Field注解
- *
- * @param clazz
- * @return
- */
- boolean createIndexIfNotExist(Class<?> clazz);
-
- /**
- * 创建索引并设置mapping,setting信息
- * 文档需标注@Document注解、包含@Id注解,其它属性字段需要添加@Field注解
- *
- * @param clazz
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- boolean createIndexIfNotExist(Class<?> clazz, boolean nonTenantMode);
-
- /**
- * 更新索引mapping信息,已存在的索引重复调用新加的字段会自动更新上去,老字段不会变化
- *
- * @param clazz
- * @return
- */
- boolean updateIndexMapping(Class<?> clazz);
-
- /**
- * 更新索引mapping信息,已存在的索引重复调用新加的字段会自动更新上去,老字段不会变化
- *
- * @param clazz
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- boolean updateIndexMapping(Class<?> clazz, boolean nonTenantMode);
-
- /**
- * 删除索引,业务应用中不建议用,如果有必要联系管理员在Kibana控台进行操作
- *
- * @param clazz
- * @return
- */
- boolean deleteIndexIfExist(Class<?> clazz);
-
- /**
- * 删除索引,业务应用中不建议用,如果有必要联系管理员在Kibana控台进行操作
- *
- * @param clazz
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- boolean deleteIndexIfExist(Class<?> clazz, boolean nonTenantMode);
-
- /**
- * 判断一个文档是否存在
- *
- * @param clazz
- * @param docId
- * @return
- */
- boolean existDocById(Class<?> clazz, String docId);
-
- /**
- * 判断一个文档是否存在
- *
- * @param clazz
- * @param docId
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- boolean existDocById(Class<?> clazz, String docId, boolean nonTenantMode);
-
- /**
- * 添加一个数据到索引中,推荐使用@addIndexDoc(T model)
- *
- * @param indexName 索引名
- * @param model 索引数据,注解@Id的字段值不允许为空
- * @return 文档ID
- */
- <T> String addIndexDoc(String indexName, T model);
-
- /**
- * 添加一个数据到索引中,推荐使用@addIndexDoc(T model)
- *
- * @param indexName 索引名
- * @param model 索引数据,注解@Id的字段值不允许为空
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return 文档ID
- */
- <T> String addIndexDoc(String indexName, T model, boolean nonTenantMode);
-
- /**
- * 添加一个数据到索引中
- * 会自动获取类上的@Document(indexName)属性当索引名
- *
- * @param model 文档数据,注解@Id的字段值不允许为空
- * @return
- */
- <T> String addIndexDoc(T model);
-
- /**
- * 添加一个数据到索引中
- * 会自动获取类上的@Document(indexName)属性当索引名
- *
- * @param model 文档数据,注解@Id的字段值不允许为空
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- <T> String addIndexDoc(T model, boolean nonTenantMode);
-
- /**
- * 添加一个数据到索引中,指定数据版本号
- *
- * @param model es文档; 文档需标注@Document注解、包含@Id注解字段, 且@Id注解标注的文档ID字段值不能为空
- * @param version 数据版本号
- * @return
- */
- <T> String saveIndexDoc(T model, Long version);
-
- /**
- * 添加一个数据到索引中,指定数据版本号
- *
- * @param model es文档; 文档需标注@Document注解、包含@Id注解字段, 且@Id注解标注的文档ID字段值不能为空
- * @param version 数据版本号
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- <T> String saveIndexDoc(T model, Long version, boolean nonTenantMode);
-
- /**
- * 添加一个数据到索引中
- * 会自动获取类上的@Document(indexName)属性当索引名
- * 指定数据版本号
- *
- * @param indexName 索引名称
- * @param model es文档; 文档需标注@Document注解、包含@Id注解字段, 且@Id注解标注的文档ID字段值不能为空
- * @param version 数据版本号
- * @return
- */
- <T> String saveIndexDoc(String indexName, T model, Long version);
-
- /**
- * 添加一个数据到索引中
- * 会自动获取类上的@Document(indexName)属性当索引名
- * 指定数据版本号
- *
- * @param indexName 索引名称
- * @param model es文档; 文档需标注@Document注解、包含@Id注解字段, 且@Id注解标注的文档ID字段值不能为空
- * @param version 数据版本号
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- <T> String saveIndexDoc(String indexName, T model, Long version, boolean nonTenantMode);
-
- /**
- * 批量添加索引,推荐使用@bulkAddIndexDoc(Class<?> clazz, List<T> docList)
- *
- * @param indexName
- * @param docList
- * @return
- */
- <T> List<IndexedObjectInformation> bulkAddIndexDoc(String indexName, List<T> docList);
-
- /**
- * 批量添加索引,推荐使用@bulkAddIndexDoc(Class<?> clazz, List<T> docList)
- *
- * @param indexName
- * @param docList
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- <T> List<IndexedObjectInformation> bulkAddIndexDoc(String indexName, List<T> docList, boolean nonTenantMode);
-
- /**
- * 批量添加索引
- *
- * @param indexName 索引名称
- * @param docList es文档集合; 文档需标注@Document注解、包含@Id、@Version注解字段, 且@Id注解标注的文档ID字段值不能为空、@Version注解标注的文档数据版本字段值不能为空
- * @return
- */
- <T> List<IndexedObjectInformation> bulkSaveIndexDoc(String indexName, List<T> docList);
-
- /**
- * 批量添加索引
- *
- * @param indexName 索引名称
- * @param docList es文档集合; 文档需标注@Document注解、包含@Id、@Version注解字段, 且@Id注解标注的文档ID字段值不能为空、@Version注解标注的文档数据版本字段值不能为空
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- <T> List<IndexedObjectInformation> bulkSaveIndexDoc(String indexName, List<T> docList, boolean nonTenantMode);
-
- /**
- * 批量添加索引,会自动获取类上的 @Document(indexName)属性当索引名
- *
- * @param clazz
- * @param docList
- * @return
- */
- <T> List<IndexedObjectInformation> bulkAddIndexDoc(Class<?> clazz, List<T> docList);
-
- /**
- * 批量添加索引,会自动获取类上的 @Document(indexName)属性当索引名
- *
- * @param clazz
- * @param docList
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- <T> List<IndexedObjectInformation> bulkAddIndexDoc(Class<?> clazz, List<T> docList, boolean nonTenantMode);
-
- /**
- * 批量添加索引
- *
- * @param clazz 会自动获取类上的 @Document(indexName)属性当索引名
- * @param docList es文档集合; 文档需标注@Document注解、包含@Id、@Version注解字段, 且@Id注解标注的文档ID字段值不能为空、@Version注解标注的文档数据版本字段值不能为空
- * @return
- */
- <T> List<IndexedObjectInformation> bulkSaveIndexDoc(Class<?> clazz, List<T> docList);
-
- /**
- * 批量添加索引
- *
- * @param clazz 会自动获取类上的 @Document(indexName)属性当索引名
- * @param docList es文档集合; 文档需标注@Document注解、包含@Id、@Version注解字段, 且@Id注解标注的文档ID字段值不能为空、@Version注解标注的文档数据版本字段值不能为空
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- <T> List<IndexedObjectInformation> bulkSaveIndexDoc(Class<?> clazz, List<T> docList, boolean nonTenantMode);
-
- /**
- * 更新文档,会自动获取类上的@Document(indexName)属性当索引名
- *
- * @param model 注解@Id的字段值不允许为空
- * @return
- */
- <T> UpdateResponse.Result updateDoc(T model);
-
- /**
- * 更新文档,会自动获取类上的@Document(indexName)属性当索引名
- *
- * @param model 注解@Id的字段值不允许为空
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- <T> UpdateResponse.Result updateDoc(T model, boolean nonTenantMode);
-
- /**
- * 批量更新文档,会自动获取类上的@Document(indexName)属性当索引名
- *
- * @param clazz
- * @param <T> 注解@Id的字段值不允许为空
- * @return
- */
- <T> List<IndexedObjectInformation> bulkUpdateDoc(Class<?> clazz, List<T> modelList);
-
- /**
- * 批量更新文档
- *
- * @param clazz
- * @param <T> 注解@Id的字段值不允许为空
- * @param bulkOptions
- * @return
- */
- <T> List<IndexedObjectInformation> bulkUpdateDoc(Class<?> clazz, List<T> modelList, BulkOptions bulkOptions);
-
- /**
- * 根据ID删除一个索引文档
- *
- * @param id
- * @param clazz
- * @return
- */
- String delIndexDoc(String id, Class<?> clazz);
-
- /**
- * 根据ID删除一个索引文档
- *
- * @param id
- * @param clazz
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- String delIndexDoc(String id, Class<?> clazz, boolean nonTenantMode);
-
- /**
- * 批量删除索引
- *
- * @param clazz
- * @param ids
- * @return
- */
- List<String> bulkDelIndexDoc(Class<?> clazz, List<String> ids);
-
- /**
- * 批量删除索引
- *
- * @param clazz
- * @param ids
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- List<String> bulkDelIndexDoc(Class<?> clazz, List<String> ids, boolean nonTenantMode);
-
- /**
- * 删除一个索引文档,会自动从类上获取注解为@Id属性的value当作ID
- *
- * @param model
- * @param <T>
- * @return
- */
- <T> String delIndexDoc(T model);
-
- /**
- * 删除一个索引文档,会自动从类上获取注解为@Id属性的value当作ID
- *
- * @param model
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- <T> String delIndexDoc(T model, boolean nonTenantMode);
-
- /**
- * @param docId
- * @param tClass
- * @param <T>
- * @return
- */
- <T> T findById(String docId, Class<T> tClass);
-
- /**
- * @param docId
- * @param clazz
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @param <T>
- * @return
- */
- <T> T findById(String docId, Class<T> clazz, boolean nonTenantMode);
-
- /**
- * 根据ID批量查询
- *
- * 使用id查询数据实时性更好
- *
- * @param indexName
- * @param clazz
- * @param docIdList
- * @param nonTenantMode
- * @param <T>
- * @return
- */
- <T> List<T> findByIds(String indexName, Class<T> clazz, List<String> docIdList, boolean nonTenantMode) ;
- <T> List<T> findByIds(Class<T> clazz, List<String> docIdList) ;
- <T> List<T> findByIds(Class<T> clazz, List<String> docIdList,boolean nonTenantMode) ;
-
-
- /**
- * 更丰富灵活的索引查询,开放spring-boot-es-starter原生NativeSearchQueryBuilder
- *
- * @param clazz 自动获取类上的@Document(indexName)属性当索引名
- * @param queryBuilder
- * @return
- */
- <T> SearchHits<T> search(Class<T> clazz, NativeSearchQueryBuilder queryBuilder);
-
- /**
- * 更丰富灵活的索引查询,开放spring-boot-es-starter原生NativeSearchQueryBuilder
- *
- * @param clazz 自动获取类上的@Document(indexName)属性当索引名
- * @param queryBuilder
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- <T> SearchHits<T> search(Class<T> clazz, NativeSearchQueryBuilder queryBuilder, boolean nonTenantMode);
-
- /**
- * 封装查询对象,简化NativeSearchQueryBuilder构造过程
- *
- * @param clazz 自动获取类上的@Document(indexName)属性当索引名
- * @param request
- * @return
- */
- <T> SearchHits<T> search(Class<T> clazz, MyEsSearchRequest request);
-
- /**
- * 封装查询对象,简化NativeSearchQueryBuilder构造过程
- *
- * @param clazz 自动获取类上的@Document(indexName)属性当索引名
- * @param request
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- <T> SearchHits<T> search(Class<T> clazz, MyEsSearchRequest request, boolean nonTenantMode);
-
- /**
- * 精确查询类场景推荐使用,es不会计算文档相关性分值,性能更好
- *
- * @param clazz 自动获取类上的@Document(indexName)属性当索引名
- * @param filterBuilder
- * @param pageable
- * @return
- */
- <T> SearchHits<T> searchByFilter(Class<T> clazz, QueryBuilder filterBuilder, @Nullable Pageable pageable);
-
- /**
- * 精确查询类场景推荐使用,es不会计算文档相关性分值,性能更好
- *
- * @param clazz 自动获取类上的@Document(indexName)属性当索引名
- * @param filterBuilder
- * @param pageable
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- <T> SearchHits<T> searchByFilter(Class<T> clazz, QueryBuilder filterBuilder, @Nullable Pageable pageable, boolean nonTenantMode);
-
- /**
- * 标题或文章内容检索类场景推荐使用,es会计算文档相关性,并按相关性自动排序
- *
- * @param clazz
- * @param queryBuilder
- * @param pageable
- * @return
- */
- <T> SearchHits<T> search(Class<T> clazz, QueryBuilder queryBuilder, @Nullable Pageable pageable);
-
- /**
- * 标题或文章内容检索类场景推荐使用,es会计算文档相关性,并按相关性自动排序
- *
- * @param clazz
- * @param queryBuilder
- * @param pageable
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- <T> SearchHits<T> search(Class<T> clazz, QueryBuilder queryBuilder, @Nullable Pageable pageable, boolean nonTenantMode);
-
- /**
- * 索引数据查询
- *
- * @param clazz 索引类
- * @param queryBuilder
- * @param filterBuilder
- * @return
- */
- <T> SearchHits<T> search(Class<T> clazz, QueryBuilder queryBuilder, QueryBuilder filterBuilder, @Nullable Pageable pageable);
-
- /**
- * 索引数据查询
- *
- * @param clazz 索引类
- * @param queryBuilder
- * @param filterBuilder
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- <T> SearchHits<T> search(Class<T> clazz, QueryBuilder queryBuilder, QueryBuilder filterBuilder, @Nullable Pageable pageable, boolean nonTenantMode);
-
- }
实现
- package com.my.elasticsearch.impl;
-
- import java.util.ArrayList;
- import java.util.List;
- import java.util.stream.Collectors;
-
- import com.my.elasticsearch.MyEsService;
- import com.my.elasticsearch.cache.EsIndexNameCache;
- import com.my.elasticsearch.util.EsReflectUtils;
- import com.my.elasticsearch.util.EsTenantUtil;
- import com.my.elasticsearch.model.MyEsSearchRequest;
- import com.fasterxml.jackson.annotation.JsonInclude;
- import com.fasterxml.jackson.core.JsonProcessingException;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import org.apache.commons.lang3.StringUtils;
- import org.elasticsearch.index.query.BoolQueryBuilder;
- import org.elasticsearch.index.query.QueryBuilder;
- import org.elasticsearch.index.query.QueryBuilders;
- import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
- import org.springframework.data.domain.Pageable;
- import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
- import org.springframework.data.elasticsearch.core.IndexedObjectInformation;
- import org.springframework.data.elasticsearch.core.MultiGetItem;
- import org.springframework.data.elasticsearch.core.MyRestIndexTemplate;
- import org.springframework.data.elasticsearch.core.SearchHits;
- import org.springframework.data.elasticsearch.core.document.Document;
- import org.springframework.data.elasticsearch.core.index.Settings;
- import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
- import org.springframework.data.elasticsearch.core.query.BulkOptions;
- import org.springframework.data.elasticsearch.core.query.FetchSourceFilter;
- import org.springframework.data.elasticsearch.core.query.IndexQuery;
- import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
- import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
- import org.springframework.data.elasticsearch.core.query.StringQuery;
- import org.springframework.data.elasticsearch.core.query.UpdateQuery;
- import org.springframework.data.elasticsearch.core.query.UpdateResponse;
- import org.springframework.lang.Nullable;
- import org.springframework.util.Assert;
- import org.springframework.util.CollectionUtils;
-
- /**
- * es 公共组件服务实现
- *
- * 该实现提供了租户也非租户模式,租户模式会给索引名前自动加租户code前缀,如果不需要可以进行修改
- *
- * @authro nantian
- * @date 2022-10-08 15:19
- */
- public class MyEsServiceImpl implements MyEsService {
- private static ObjectMapper objectMapper;
- private ElasticsearchRestTemplate elasticsearchRestTemplate;
- private static final String PROPERTIES_KEY = "properties";
-
- public MyEsServiceImpl(ElasticsearchRestTemplate elasticsearchRestTemplate) {
- this.elasticsearchRestTemplate = elasticsearchRestTemplate;
- }
-
- static {
- //JavaTimeModule timeModule = new JavaTimeModule();
- //timeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
- //timeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
- 设置NULL值不参与序列化
- objectMapper = new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL);
- //.registerModule(timeModule);
- }
-
- /**
- * 根据使用的租户模式,决定是否对索引名添加租户标识
- *
- * @param index
- * @return
- */
- private String convertTenantIndex(String index) {
- return EsTenantUtil.getTenantIndex(index);
- }
-
- /**
- * 构建操作es的索引类
- *
- * @param index
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- private IndexCoordinates buildIndexCoordinates(String index, boolean nonTenantMode) {
- if (!nonTenantMode) {
- index = convertTenantIndex(index);
- }
- return IndexCoordinates.of(index);
- }
-
- private IndexCoordinates buildIndexCoordinates(Class<?> clazz) {
- return buildIndexCoordinates(clazz, false);
- }
-
- private IndexCoordinates buildIndexCoordinates(Class<?> clazz, boolean nonTenantMode) {
- if (!nonTenantMode) {
- return IndexCoordinates.of(convertTenantIndex(getEsIndexName(clazz)));
- }
- return IndexCoordinates.of(getEsIndexName(clazz));
- }
-
- /**
- * 根据类@Document(indexName)属性获取索引名
- *
- * @param clazz
- * @return
- */
- private String getEsIndexName(Class<?> clazz) {
- return EsIndexNameCache.get(clazz);
- }
-
- /**
- * 判断索引是否存在
- *
- * @param indexName 索引名称
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- public boolean existIndex(String indexName, boolean nonTenantMode) {
- if (StringUtils.isNotEmpty(indexName)) {
- return elasticsearchRestTemplate.indexOps(buildIndexCoordinates(indexName, nonTenantMode)).exists();
- }
- return Boolean.FALSE;
- }
-
- /**
- * 判断索引是否存在
- *
- * @param clazz
- * @return
- */
- @Override
- public boolean existIndex(Class<?> clazz) {
- return existIndex(clazz, false);
- }
-
- @Override
- public boolean existIndex(Class<?> clazz, boolean nonTenantMode) {
- if (clazz != null) {
- return existIndex(getEsIndexName(clazz), nonTenantMode);
- }
- return Boolean.FALSE;
- }
-
- /**
- * 索引不存在时创建索引[无分片及mapping信息,暂不开放使用]
- *
- * @param indexName 索引名称
- * @return 是否创建成功
- */
- private boolean createIndexIfNotExist(String indexName) {
- return createIndexIfNotExist(indexName, false);
- }
-
- /**
- * 索引不存在时创建索引[无分片及mapping信息,暂不开放使用]
- *
- * @param indexName 索引名称
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return 是否创建成功
- */
- private boolean createIndexIfNotExist(String indexName, boolean nonTenantMode) {
- if (!existIndex(indexName, nonTenantMode)) {
- return elasticsearchRestTemplate.indexOps(buildIndexCoordinates(indexName, nonTenantMode)).create();
- }
- return Boolean.FALSE;
- }
-
- /**
- * 索引不存在时创建索引并设置分片及mapping信息
- *
- * @param clazz 索引类信息
- * @return 是否创建成功
- */
- @Override
- public boolean createIndexIfNotExist(Class<?> clazz) {
- return createIndexIfNotExist(clazz, false);
- }
-
- @Override
- public boolean createIndexIfNotExist(Class<?> clazz, boolean nonTenantMode) {
- boolean result = existIndex(clazz, nonTenantMode);
- if (!result) {
- //不能直接用createWithMapping,会漏掉租户信息,改写索引类上租户实现比较复杂
- //elasticsearchRestTemplate.indexOps(clazz).createWithMapping();
- MyRestIndexTemplate esRestIndexTemplate = new MyRestIndexTemplate(elasticsearchRestTemplate, clazz);
- Document document = esRestIndexTemplate.createMapping();
- Settings settings = esRestIndexTemplate.createSettings();
-
- return esRestIndexTemplate.doCreate(buildIndexCoordinates(clazz, nonTenantMode), settings, document);
- }
- return Boolean.FALSE;
- }
-
- /**
- * 更新索引字段,会自动获取类上的索引注解信息进行更新索引mapping,已存在的字段不会更新
- *
- * @param clazz
- * @return
- */
- @Override
- public boolean updateIndexMapping(Class<?> clazz) {
- return updateIndexMapping(clazz, false);
- }
-
- @Override
- public boolean updateIndexMapping(Class<?> clazz, boolean nonTenantMode) {
- boolean result = existIndex(clazz, nonTenantMode);
- if (result) {
- MyRestIndexTemplate esRestIndexTemplate = new MyRestIndexTemplate(elasticsearchRestTemplate, clazz);
- Document document = esRestIndexTemplate.createMapping();
- return esRestIndexTemplate.doPutMapping(buildIndexCoordinates(clazz, nonTenantMode), document);
- }
- return Boolean.FALSE;
- }
-
- /**
- * 索引存在删除索引
- *
- * @param indexName 索引名称
- * @return 是否删除成功
- */
- public boolean deleteIndexIfExist(String indexName) {
- return deleteIndexIfExist(indexName, false);
- }
-
- /**
- * 索引存在删除索引
- *
- * @param indexName 索引名称
- * @return 是否删除成功
- */
- public boolean deleteIndexIfExist(String indexName, boolean nonTenantMode) {
- if (existIndex(indexName, nonTenantMode)) {
- return elasticsearchRestTemplate.indexOps(buildIndexCoordinates(indexName, nonTenantMode)).delete();
- }
- return Boolean.FALSE;
- }
-
- /**
- * 索引存在删除索引
- *
- * @param clazz 索引名称
- * @return 是否删除成功
- */
- @Override
- public boolean deleteIndexIfExist(Class<?> clazz) {
- if (existIndex(clazz)) {
- return deleteIndexIfExist(getEsIndexName(clazz));
- }
- return Boolean.FALSE;
- }
-
- @Override
- public boolean deleteIndexIfExist(Class<?> clazz, boolean nonTenantMode) {
- if (existIndex(clazz, nonTenantMode)) {
- return deleteIndexIfExist(getEsIndexName(clazz), nonTenantMode);
- }
- return Boolean.FALSE;
- }
-
- /**
- * 新增索引文档,根据类上的@Document获取索引名
- *
- * @param model elasticsearch文档; 文档需标注@Document注解、包含@Id注解字段, 且@Id注解标注的文档ID字段值不能为空
- * @return 文档ID
- */
- @Override
- public <T> String addIndexDoc(T model) {
- return addIndexDoc(getEsIndexName(model.getClass()), model);
- }
-
- @Override
- public <T> String addIndexDoc(T model, boolean nonTenantMode) {
- return addIndexDoc(getEsIndexName(model.getClass()), model, nonTenantMode);
- }
-
- /**
- * 新增文档,指定索引名
- *
- * @param indexName 索引名称
- * @param model es文档; 文档需标注@Document注解、包含@Id注解字段, 且@Id注解标注的文档ID字段值不能为空
- * @return 文档ID
- */
- @Override
- public <T> String addIndexDoc(String indexName, T model) {
- return addIndexDoc(indexName, model, false);
- }
-
- @Override
- public <T> String addIndexDoc(String indexName, T model, boolean nonTenantMode) {
- Assert.notNull(indexName, "addIndexDoc elasticsearch indexName is null");
- Assert.notNull(model, "addIndexDoc document is null");
- return elasticsearchRestTemplate.index(
- new IndexQueryBuilder().withId(getDocumentIdValue(model)).withObject(model).build(),
- buildIndexCoordinates(indexName, nonTenantMode));
- }
-
- /**
- * 保存文档,指定数据版本号
- *
- * @param model es文档; 文档需标注@Document注解、包含@Id注解字段, 且@Id注解标注的文档ID字段值不能为空
- * @param version 数据版本号
- * @param <T>
- * @return
- */
- @Override
- public <T> String saveIndexDoc(T model, Long version) {
- return saveIndexDoc(model, version, false);
- }
-
- @Override
- public <T> String saveIndexDoc(T model, Long version, boolean nonTenantMode) {
- return saveIndexDoc(getEsIndexName(model.getClass()), model, version, nonTenantMode);
- }
-
- /**
- * 保存文档,指定索引名和数据版本号
- *
- * @param indexName 索引名称
- * @param model es文档; 文档需标注@Document注解、包含@Id注解字段, 且@Id注解标注的文档ID字段值不能为空
- * @param version 数据版本号
- * @return 文档ID
- */
- @Override
- public <T> String saveIndexDoc(String indexName, T model, Long version) {
- return saveIndexDoc(indexName, model, version, false);
- }
-
- /**
- * 保存文档,指定索引名和数据版本号
- *
- * @param indexName 索引名称
- * @param model es文档; 文档需标注@Document注解、包含@Id注解字段, 且@Id注解标注的文档ID字段值不能为空
- * @param version 数据版本号
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return 文档ID
- */
- @Override
- public <T> String saveIndexDoc(String indexName, T model, Long version, boolean nonTenantMode) {
- Assert.notNull(indexName, "addIndexDoc elasticsearch indexName is null");
- Assert.notNull(model, "addIndexDoc document is null");
- return elasticsearchRestTemplate.index(
- new IndexQueryBuilder().withId(getDocumentIdValue(model)).withVersion(version).withObject(model).build(),
- buildIndexCoordinates(indexName, nonTenantMode));
- }
-
- @Override
- public <T> List<IndexedObjectInformation> bulkAddIndexDoc(Class<?> clazz, List<T> docList) {
- return bulkAddIndexDoc(getEsIndexName(clazz), docList);
- }
-
- @Override
- public <T> List<IndexedObjectInformation> bulkAddIndexDoc(Class<?> clazz, List<T> docList, boolean nonTenantMode) {
- return bulkAddIndexDoc(getEsIndexName(clazz), docList, nonTenantMode);
- }
-
- @Override
- public <T> List<IndexedObjectInformation> bulkSaveIndexDoc(Class<?> clazz, List<T> docList) {
- return bulkSaveIndexDoc(clazz, docList, false);
- }
-
- @Override
- public <T> List<IndexedObjectInformation> bulkSaveIndexDoc(Class<?> clazz, List<T> docList, boolean nonTenantMode) {
- return bulkSaveIndexDoc(getEsIndexName(clazz), docList, nonTenantMode);
- }
-
- /**
- * 批量新增文档
- *
- * @param indexName 索引名称
- * @param docList es文档集合; 文档需标注@Document注解、包含@Id注解字段, 且@Id注解标注的文档ID字段值不能为空
- * @return 文档ID
- */
- public <T> List<IndexedObjectInformation> bulkAddIndexDoc(String indexName, List<T> docList) {
- return bulkAddIndexDoc(indexName, docList, false);
- }
-
- /**
- * 批量新增文档
- *
- * @param indexName 索引名称
- * @param docList es文档集合; 文档需标注@Document注解、包含@Id注解字段, 且@Id注解标注的文档ID字段值不能为空
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return 文档ID
- */
- @Override
- public <T> List<IndexedObjectInformation> bulkAddIndexDoc(String indexName, List<T> docList, boolean nonTenantMode) {
- Assert.notNull(indexName, "bulkAddIndexDoc elasticsearch indexName is null");
- Assert.notNull(docList, "bulkAddIndexDoc document is null");
-
- List<IndexQuery> indexQueries = new ArrayList<>();
- docList.forEach(doc ->
- indexQueries.add(new IndexQueryBuilder().withId(getDocumentIdValue(doc)).withObject(doc).build()));
-
- return elasticsearchRestTemplate.bulkIndex(indexQueries, buildIndexCoordinates(indexName, nonTenantMode));
- }
-
- /**
- * 批量新增文档
- *
- * @param indexName 索引名称
- * @param docList es文档集合; 文档需标注@Document注解、包含@Id、@Version注解字段, 且@Id注解标注的文档ID字段值不能为空、@Version注解标注的文档数据版本字段值不能为空
- * @param <T>
- * @return
- */
- @Override
- public <T> List<IndexedObjectInformation> bulkSaveIndexDoc(String indexName, List<T> docList) {
- return bulkSaveIndexDoc(indexName, docList, false);
- }
-
- /**
- * 批量新增文档
- *
- * @param indexName 索引名称
- * @param docList es文档集合; 文档需标注@Document注解、包含@Id、@Version注解字段, 且@Id注解标注的文档ID字段值不能为空、@Version注解标注的文档数据版本字段值不能为空
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return
- */
- @Override
- public <T> List<IndexedObjectInformation> bulkSaveIndexDoc(String indexName, List<T> docList, boolean nonTenantMode) {
- Assert.notNull(indexName, "bulkAddIndexDoc elasticsearch indexName is null");
- Assert.notNull(docList, "bulkAddIndexDoc document is null");
-
- // 验证是否传version值
- docList.forEach(doc -> getDocumentVersionValue(doc));
-
- List<IndexQuery> indexQueries = new ArrayList<>();
- docList.forEach(doc ->
- indexQueries.add(new IndexQueryBuilder().withId(getDocumentIdValue(doc)).withVersion(getDocumentVersionValue(doc)).withObject(doc).build()));
-
- return elasticsearchRestTemplate.bulkIndex(indexQueries, buildIndexCoordinates(indexName, nonTenantMode));
- }
-
- /**
- * 根据ID查询文档
- *
- * @param indexName 索引名称
- * @param docId 文档ID
- * @param clazz 映射类Class
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @param <T>
- * @return Elasticsearch 文档
- */
- public <T> T findById(String indexName, String docId, Class<T> clazz, boolean nonTenantMode) {
- if (StringUtils.isNotEmpty(docId) && clazz != null) {
- return elasticsearchRestTemplate.get(docId, clazz, buildIndexCoordinates(indexName, nonTenantMode));
- }
- return null;
- }
-
- public <T> T findById(String docId, Class<T> clazz) {
- return findById(docId, clazz, false);
- }
-
- @Override
- public <T> T findById(String docId, Class<T> clazz, boolean nonTenantMode) {
- return findById(getEsIndexName(clazz), docId, clazz, nonTenantMode);
- }
-
-
- /**
- * 根据多个ID查询文档
- *
- * @param indexName 索引名称
- * @param docIdList 文档ID
- * @param clazz 映射类Class
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @param <T>
- * @return Elasticsearch 文档
- */
- @Override
- public <T> List<T> findByIds(String indexName, Class<T> clazz, List<String> docIdList, boolean nonTenantMode) {
- if (CollectionUtils.isEmpty(docIdList) || clazz == null || indexName == null) {
- return null;
- }
- StringQuery query = StringQuery.builder("stringQuery").withIds(docIdList).build();
- List<MultiGetItem<T>> result = elasticsearchRestTemplate.multiGet(query, clazz, buildIndexCoordinates(indexName, nonTenantMode));
- if(CollectionUtils.isEmpty(result)){
- return null;
- }
-
- List list = result.stream().map(o->o.getItem()).filter(item->item != null).collect(Collectors.toList());
- return list;
- }
-
- @Override
- public <T> List<T> findByIds(Class<T> clazz,List<String> docIdList) {
- return findByIds( clazz, docIdList,false);
- }
-
- @Override
- public <T> List<T> findByIds(Class<T> clazz, List<String> docIdList,boolean nonTenantMode) {
- return findByIds(getEsIndexName(clazz), clazz,docIdList, nonTenantMode);
- }
-
- /**
- * 根据ID判断文档是否存在
- *
- * @param indexName 索引名称
- * @param docId 文档ID
- * @return 存在与否
- */
- private boolean existDocById(String indexName, String docId, boolean nonTenantMode) {
- if (existIndex(indexName, nonTenantMode) && StringUtils.isNotEmpty(docId)) {
- return elasticsearchRestTemplate.exists(docId, buildIndexCoordinates(indexName, nonTenantMode));
- }
- return Boolean.FALSE;
- }
-
- public boolean existDocById(Class<?> clazz, String docId) {
- return existDocById(clazz, docId, false);
- }
-
- @Override
- public boolean existDocById(Class<?> clazz, String docId, boolean nonTenantMode) {
- return existDocById(getEsIndexName(clazz), docId, nonTenantMode);
- }
-
- public <T> UpdateResponse.Result updateDoc(T elasticsearchModel) {
- return updateDoc(elasticsearchModel, false);
- }
-
- @Override
- public <T> UpdateResponse.Result updateDoc(T elasticsearchModel, boolean nonTenantMode) {
- String indexName = getEsIndexName(elasticsearchModel.getClass());
- return updateDoc(indexName, elasticsearchModel, nonTenantMode);
- }
-
- /**
- * 更新文档
- *
- * @param indexName 索引名称
- * @param elasticsearchModel elasticsearch文档; 文档需标注@Document注解、包含@Id注解字段, 且@Id标注的文档ID值不能为空
- * @return UpdateResponse.Result
- * @throws JsonProcessingException JsonProcessingException
- */
- private <T> UpdateResponse.Result updateDoc(String indexName, T elasticsearchModel, boolean nonTenantMode) {
- return updateDoc(indexName, elasticsearchModel, this.objectMapper, nonTenantMode);
- }
-
- /**
- * 更新文档
- *
- * @param indexName 索引名称
- * @param elasticsearchModel elasticsearch文档; 文档需标注@Document注解、包含@Id注解字段, 且@Id标注的文档ID值不能为空
- * @param objectMapper objectMapper
- * @return UpdateResponse.Result
- */
- private <T> UpdateResponse.Result updateDoc(String indexName, T elasticsearchModel, ObjectMapper objectMapper) {
- return updateDoc(indexName, elasticsearchModel, objectMapper, false);
- }
-
- /**
- * 更新文档
- *
- * @param indexName 索引名称
- * @param elasticsearchModel elasticsearch文档; 文档需标注@Document注解、包含@Id注解字段, 且@Id标注的文档ID值不能为空
- * @param objectMapper objectMapper
- * @param nonTenantMode 是否是租户模式,false表示非租户模式,即通用索引
- * @return UpdateResponse.Result
- */
- private <T> UpdateResponse.Result updateDoc(String indexName, T elasticsearchModel, ObjectMapper objectMapper, boolean nonTenantMode) {
- Assert.notNull(indexName, "bulkUpdateDoc clazz is null");
- Assert.notNull(elasticsearchModel, "bulkUpdateDoc modelList is null");
- try {
- String id = getDocumentIdValue(elasticsearchModel);
- Assert.isTrue(existDocById(indexName, id, nonTenantMode), "elasticsearch document is not exist.");
-
- objectMapper = objectMapper == null ? this.objectMapper : objectMapper;
- String json = objectMapper.writeValueAsString(elasticsearchModel);
- UpdateQuery updateQuery = UpdateQuery.builder(id).withDocument(Document.parse(json)).build();
-
- return elasticsearchRestTemplate.update(updateQuery, buildIndexCoordinates(indexName, nonTenantMode)).getResult();
- } catch (JsonProcessingException e) {
- e.printStackTrace();
- throw new RuntimeException(e);
- }
- }
-
- public <T> List<IndexedObjectInformation> bulkUpdateDoc(Class<?> clazz, List<T> modelList) {
- return bulkUpdateDoc(clazz, modelList, null);
- }
-
- public <T> List<IndexedObjectInformation> bulkUpdateDoc(Class<?> clazz, List<T> modelList, BulkOptions bulkOptions) {
- return bulkUpdateDoc(clazz, modelList, bulkOptions, objectMapper);
- }
-
-
- /**
- * 批量更新文档
- *
- * @param clazz 索引名称
- * @param modelList elasticsearch文档; 文档需标注@Document注解、包含@Id注解字段, 且@Id标注的文档ID值不能为空
- * @param objectMapper objectMapper
- * @return UpdateResponse.Result
- */
- private <T> List<IndexedObjectInformation> bulkUpdateDoc(Class<?> clazz, List<T> modelList, BulkOptions bulkOptions,
- ObjectMapper objectMapper) {
- Assert.notNull(clazz, "bulkUpdateDoc clazz is null");
- Assert.notNull(clazz, "bulkUpdateDoc modelList is null");
-
- try {
- List<UpdateQuery> queries = new ArrayList(modelList.size());
- UpdateQuery updateQuery = null;
- String id = null;
- for (T model : modelList) {
- id = getDocumentIdValue(model);
- Assert.notNull(id, clazz.getName() + " instance document id is null");
- String json = objectMapper.writeValueAsString(model);
- updateQuery = UpdateQuery.builder(getDocumentIdValue(model)).withDocument(Document.parse(json)).build();
- queries.add(updateQuery);
- }
- bulkOptions = bulkOptions == null ? BulkOptions.defaultOptions() : bulkOptions;
- return elasticsearchRestTemplate.doBulkOperation(queries, bulkOptions, buildIndexCoordinates(clazz));
- } catch (Exception e) {
- e.printStackTrace();
- throw new RuntimeException(e);
- }
- }
-
- private <T> String getDocumentIdValue(T elasticsearchModel) {
- return EsReflectUtils.getDocumentIdValue(elasticsearchModel);
- }
-
- private <T> Long getDocumentVersionValue(T elasticsearchModel) {
- return EsReflectUtils.getDocumentVersionValue(elasticsearchModel);
- }
-
- /**
- * 查询文档
- *
- * @param clazz 映射文档类 文档需标注@Document注解、包含@Id注解字段
- * @param queryBuilder 非结构化数据 QueryBuilder; queryBuilder与filterBuilder必须二者存在其一
- * @param filterBuilder 过滤查询
- * @param <T>
- * @return
- */
- public <T> SearchHits<T> search(Class<T> clazz, QueryBuilder queryBuilder, QueryBuilder filterBuilder,
- Pageable pageable) {
- MyEsSearchRequest request = new MyEsSearchRequest(queryBuilder, filterBuilder, pageable);
- return search(clazz, request);
- }
-
- @Override
- public <T> SearchHits<T> search(Class<T> clazz, QueryBuilder queryBuilder, QueryBuilder filterBuilder,
- Pageable pageable, boolean nonTenantMode) {
- MyEsSearchRequest request = new MyEsSearchRequest(queryBuilder, filterBuilder, pageable);
- return search(clazz, request, nonTenantMode);
- }
-
- public <T> SearchHits<T> searchByFilter(Class<T> clazz, QueryBuilder filterBuilder, Pageable pageable) {
- MyEsSearchRequest request = new MyEsSearchRequest(null, filterBuilder, pageable);
- return search(clazz, request);
- }
-
- @Override
- public <T> SearchHits<T> searchByFilter(Class<T> clazz, QueryBuilder filterBuilder, @javax.annotation.Nullable Pageable pageable, boolean nonTenantMode) {
- MyEsSearchRequest request = new MyEsSearchRequest(null, filterBuilder, pageable);
- return search(clazz, request, nonTenantMode);
- }
-
- public <T> SearchHits<T> search(Class<T> clazz, QueryBuilder queryBuilder, Pageable pageable) {
- MyEsSearchRequest request = new MyEsSearchRequest(queryBuilder, null, pageable);
- return search(clazz, request);
- }
-
- @Override
- public <T> SearchHits<T> search(Class<T> clazz, QueryBuilder queryBuilder, @javax.annotation.Nullable Pageable pageable, boolean nonTenantMode) {
- MyEsSearchRequest request = new MyEsSearchRequest(queryBuilder, null, pageable);
- return search(clazz, request, nonTenantMode);
- }
-
- public <T> SearchHits<T> search(Class<T> clazz, MyEsSearchRequest request) {
- return search(clazz, request, false);
- }
-
- @Override
- public <T> SearchHits<T> search(Class<T> clazz, MyEsSearchRequest request, boolean nonTenantMode) {
- return search(getEsIndexName(clazz), clazz, request.getQueryBuilder(), request.getFilterBuilder(),
- request.getAggregationBuilder(), request.getPageable(), request.getQueryFields(), nonTenantMode);
- }
-
- public <T> SearchHits<T> search(Class<T> clazz, NativeSearchQueryBuilder queryBuilder) {
- return search(clazz, queryBuilder, false);
- }
-
- @Override
- public <T> SearchHits<T> search(Class<T> clazz, NativeSearchQueryBuilder queryBuilder, boolean nonTenantMode) {
- return elasticsearchRestTemplate.search(queryBuilder.build(), clazz, buildIndexCoordinates(clazz, nonTenantMode));
- }
-
- /**
- * 查询文档
- *
- * <p>
- * 查询的文档必须包含映射@Document的@Id字段
- * </p>
- *
- * @param indexName 索引名称
- * @param clazz 映射文档类 文档需标注@Document注解、包含@Id注解字段
- * @param queryBuilder 非结构化数据 QueryBuilder; queryBuilder与filterBuilder必须二者存在其一
- * @param filterBuilder 结构化数据 QueryBuilder; filterBuilder与queryBuilder必须二者存在其一
- * @param abstractAggregationBuilder 聚合查询Builder
- * @param pageable 分页/排序; 分页从0开始
- * @param fields 包含字段
- * @param nonTenantMode 是否是租户模式,false表示非租户模式,即通用索引
- * @return
- */
- private <T> SearchHits<T> search(String indexName, Class<T> clazz, @Nullable QueryBuilder queryBuilder,
- @Nullable QueryBuilder filterBuilder,
- @Nullable AbstractAggregationBuilder abstractAggregationBuilder,
- @Nullable Pageable pageable, @Nullable String[] fields, boolean nonTenantMode) {
- if (StringUtils.isNotBlank(indexName)) {
- // 查询的文档必须包含映射@Document的@Id字段(
- BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery().must(
- QueryBuilders.existsQuery(EsReflectUtils.getDocumentIdFieldName(clazz)));
- if (queryBuilder != null) {
- boolQueryBuilder.must(queryBuilder);
- }
- NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder().withQuery(
- boolQueryBuilder);
- if (filterBuilder != null) {
- nativeSearchQueryBuilder.withFilter(filterBuilder);
- }
- if (abstractAggregationBuilder != null) {
- nativeSearchQueryBuilder.withAggregations(abstractAggregationBuilder);
- }
- if (pageable != null) {
- nativeSearchQueryBuilder.withPageable(pageable);
- }
- if (fields != null && fields.length > 0) {
- nativeSearchQueryBuilder.withSourceFilter(new FetchSourceFilter(fields, null));
- //nativeSearchQueryBuilder.withFields(fields);
- }
- // nativeSearchQueryBuilder.withSorts(SortBuilders.fieldSort("id").order(SortOrder.ASC));
- return search(clazz, nativeSearchQueryBuilder, nonTenantMode);
- }
- return null;
- }
-
- @Override
- public String delIndexDoc(String id, Class<?> clazz) {
- return delIndexDoc(id, clazz, false);
- }
-
- @Override
- public String delIndexDoc(String id, Class<?> clazz, boolean nonTenantMode) {
- return elasticsearchRestTemplate.delete(id, buildIndexCoordinates(clazz, nonTenantMode));
- }
-
- @Override
- public <T> String delIndexDoc(T model) {
- return delIndexDoc(model, false);
- }
-
- @Override
- public <T> String delIndexDoc(T model, boolean nonTenantMode) {
- return delIndexDoc(EsReflectUtils.getDocumentIdValue(model), model.getClass(), nonTenantMode);
- }
-
- /**
- * 根据ID批量删除
- * 官方未提供根据id批量删除的,暂时就以循环删除的方式来操作,若有大批量操作存在性能问题考虑转为query delete方式
- *
- * @param clazz
- * @param ids
- * @return 返回每个ID删除后的返回结果
- */
- @Override
- public List<String> bulkDelIndexDoc(Class<?> clazz, List<String> ids) {
- return bulkDelIndexDoc(clazz, ids, false);
- }
-
- /**
- * 根据ID批量删除
- * 官方未提供根据id批量删除的,暂时就以循环删除的方式来操作,若有大批量操作存在性能问题考虑转为query delete方式
- *
- * @param clazz
- * @param ids
- * @param nonTenantMode 是否是租户模式,true表示非租户模式,即通用索引
- * @return 返回每个ID删除后的返回结果
- */
- @Override
- public List<String> bulkDelIndexDoc(Class<?> clazz, List<String> ids, boolean nonTenantMode) {
- if (clazz == null || CollectionUtils.isEmpty(ids)) {
- return null;
- }
- List delResutList = new ArrayList();
- for (String id : ids) {
- delResutList.add(elasticsearchRestTemplate.delete(id, buildIndexCoordinates(clazz, nonTenantMode)));
- }
- return delResutList;
- }
-
- }
增删改查demo
- package com.my.es.test;
-
- import java.util.Date;
- import java.util.List;
-
-
- import com.my.elasticsearch.MyEsService;
- import com.my.es.test.model.Shop;
- import com.my.es.test.model.Student;
- import com.my.elasticsearch.model.MyEsSearchRequest;
- import com.fasterxml.jackson.core.JsonProcessingException;
- import net.minidev.json.JSONObject;
- import org.assertj.core.util.Lists;
- import org.elasticsearch.index.query.BoolQueryBuilder;
- import org.elasticsearch.index.query.MatchQueryBuilder;
- import org.elasticsearch.index.query.QueryBuilder;
- import org.elasticsearch.index.query.QueryBuilders;
- import org.elasticsearch.index.query.RangeQueryBuilder;
- import org.junit.Assert;
- import org.junit.jupiter.api.Test;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.boot.test.context.SpringBootTest;
- import org.springframework.data.domain.PageRequest;
- import org.springframework.data.domain.Sort;
- import org.springframework.data.domain.Sort.Direction;
- import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
- import org.springframework.data.elasticsearch.core.IndexedObjectInformation;
- import org.springframework.data.elasticsearch.core.SearchHits;
- import org.springframework.data.elasticsearch.core.query.UpdateResponse;
- import org.springframework.data.elasticsearch.core.query.UpdateResponse.Result;
-
- /**
- * es demo
- *
- * @authro nantian
- * @date 2022-10-08 19:33
- */
- @SpringBootTest
- public class MyEsServiceTest {
- @Autowired
- private MyEsService myEsService;
-
- @Autowired
- private ElasticsearchRestTemplate elasticsearchRestTemplate;
-
- @Test
- public void delIndex() {
- boolean result = myEsService.deleteIndexIfExist(Student.class);
- Assert.assertTrue(result);
- }
-
- @Test
- public void delIndexDoc() {
- String result = myEsService.delIndexDoc("3007", Student.class);
- System.out.println("delIndexDoc:" + Student.class.getName());
- }
-
-
- @Test
- public void updateMapping() {
- boolean result = myEsService.updateIndexMapping(Student.class);
- Assert.assertTrue(result);
- }
-
-
- @Test
- public void updateIndexMapping() {
- boolean result = myEsService.updateIndexMapping(Shop.class);
- Assert.assertTrue(result);
- }
-
- @Test
- public void createIndex() {
- boolean exist = myEsService.existIndex(Student.class);
- boolean result = false;
- if (!exist) {
- result = myEsService.createIndexIfNotExist(Student.class);
- } else {
- System.out.println("index exist:" + Student.class.getName());
- }
- Assert.assertTrue(result);
- }
-
-
-
- @Test
- public void createIndex3() {
- boolean result = myEsService.createIndexIfNotExist(Shop.class);
- System.out.println("index exist:" + Shop.class.getName());
- Assert.assertTrue(result);
- }
-
- @Test
- public void addIndexDoc() {
- Student student = new Student(1000, "张三", "测试索引添加", "哈哈", "三年二班刘", 10, new Date(), null);
- String documentId = myEsService.addIndexDoc(student);
- System.out.println("addIndexDoc result:" + documentId);
- Assert.assertNotNull(documentId);
- }
-
- @Test
- public void saveIndexDocWithVersion() {
- Student student = new Student(1009, "张三1001", "测试索引添加1", "哈哈", "三年二班刘11", 10, new Date(), null);
- Student existOne = myEsService.findById(student.getId() + "", Student.class);
- Long _version = existOne != null ? existOne.getVersion() + 1 : null;
- String documentId = myEsService.saveIndexDoc(student, _version);
- System.out.println("addIndexDoc result:" + documentId);
- Assert.assertNotNull(documentId);
- }
-
- @Test
- public void existIndex() {
- boolean result1 = myEsService.existIndex(Student.class);
- boolean result2 = myEsService.existIndex(Student.class, true);
- System.out.println(result1 + "------" + result2);
- }
-
- @Test
- public void saveIndexDocWithNonTenantModel() {
- Student student = new Student(1001, "张三1001", "测试索引添加1", "哈哈", "三年二班刘11", 10, new Date(), null);
- boolean nonTenantModel = true;
- if (nonTenantModel) {
- if (!myEsService.existIndex(Student.class, nonTenantModel)) {
- myEsService.createIndexIfNotExist(Student.class, nonTenantModel);
- }
-
- }
- Student existOne = myEsService.findById(student.getId() + "", Student.class, nonTenantModel);
- Long _version = existOne != null ? existOne.getVersion() + 1 : null;
- String documentId = myEsService.saveIndexDoc(student, _version, nonTenantModel);
- System.out.println("addIndexDoc result:" + documentId);
- Assert.assertNotNull(documentId);
- }
-
-
- @Test
- public void bulkAddIndexDoc2() {
- Student student1 = new Student(1000, "zs0", "测试索引添加0", "哈哈33ss", "三年二班刘先生中国", 10, new Date(), null);
- Student student2 = new Student(1001, "zs", "测试索引添加1", "哈哈dd", "五年二班周先生美国", 20, new Date(), null);
- Student student3 = new Student(1002, "zs", "测试索引添加2", "哈哈aa", "10年二班刘女士中国", 0, new Date(), null);
- Student student4 = new Student(1003, "zs1003", "测试索引添加3", "哈哈aadd", "八年二班张女士北京", 50, new Date(), null);
- Student student5 = new Student(1004, "zs1004", "测试索引添加4", "哈哈bbaa", "三年二班刘重生北京", 60, new Date(), null);
- Student student6 = new Student(1006, "zs1006", "测试索引添加4", "哈哈bbaa", "三年二班刘重生北京", 60, new Date(), null);
- Student student7 = new Student(1007, "zs1007", "测试索引添加4", "哈哈bbaa", "三年二班刘重生北京", 60, new Date(), null);
- List list = Lists.newArrayList(student1, student2, student3, student4, student5, student6, student7);
- List<IndexedObjectInformation> result = myEsService.bulkAddIndexDoc(Student.class, list);
- System.out.println("bulkAddIndexDoc result:" + JSONObject.toJSONString(result));
- Assert.assertNotNull(result.size() > 0);
- }
-
- @Test
- public void bulkSaveIndexDoc() {
- Student student1 = new Student(1020, "zs0", "测试索引添加0", "哈哈33ss", "三年二班刘先生中国", 11, new Date(), null);
- Student student2 = new Student(1021, "zs", "测试索引添加1", "哈哈dd", "五年二班周先生美国", 12, new Date(), null);
- Student student3 = new Student(1022, "zs", "测试索引添加2", "哈哈aa", "10年二班刘女士中国", 13, new Date(), null);
- List<Student> list = Lists.newArrayList(student1, student2, student3);
-
- for (Student student : list) {
- Student existOne = myEsService.findById(student.getId() + "", Student.class);
- Long _version = existOne != null ? existOne.getVersion() + 1 : 1;
- student.setVersion(_version);
- }
-
- List<IndexedObjectInformation> result = myEsService.bulkSaveIndexDoc(Student.class, list);
- System.out.println("bulkAddIndexDoc result:" + JSONObject.toJSONString(result));
- Assert.assertNotNull(result.size() > 0);
- }
-
- @Test
- public void getByIdStudent() {
- Student student = myEsService.findById("1000", Student.class);
- System.out.println(JSONObject.toJSONString(student));
- }
-
- @Test
- public void updateDoc() throws JsonProcessingException {
- Student student = new Student();
- student.setId(1000);
- student.setAge(30);
- student.setText("lisi");
- UpdateResponse.Result result = myEsService.updateDoc(student);
- System.out.println("update result:" + JSONObject.toJSONString(result));
- Student student2 = myEsService.findById("1000", Student.class);
- System.out.println(JSONObject.toJSONString(student2));
- Assert.assertTrue(Result.UPDATED == result);
- }
-
- @Test
- public void searchAll() {
- SearchHits<Student> hits = myEsService.search(Student.class, QueryBuilders.matchAllQuery(), null);
- System.out.println(JSONObject.toJSONString(hits));
- }
-
- @Test
- public void searchBySingleField() {
- QueryBuilder queryBuilder = QueryBuilders.matchQuery("name", "zs0");
- SearchHits<Student> hits = myEsService.search(Student.class, queryBuilder, null);
- System.out.println(JSONObject.toJSONString(hits));
- }
-
- @Test
- public void searchByFilter() {
- MyEsSearchRequest request = new MyEsSearchRequest();
- request.setQueryFields(new String[]{"name", "id", "_version"});
-
- //1
- QueryBuilder queryBuilder = QueryBuilders.multiMatchQuery("zs", "name", "text");
- request.setQueryBuilder(queryBuilder);
-
- //2
- MatchQueryBuilder queryBuilder1 = QueryBuilders.matchQuery("name", "zs");
- RangeQueryBuilder queryBuilder2 = QueryBuilders.rangeQuery("age").gte("10").lte("60");
- MatchQueryBuilder fuzzyQueryBuilder = QueryBuilders.matchQuery("desc", "哈哈");
-
- BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
- boolQueryBuilder.should(queryBuilder1);
- boolQueryBuilder.should(queryBuilder2);
- boolQueryBuilder.should(fuzzyQueryBuilder);
-
- BoolQueryBuilder filterQueryBuilder = QueryBuilders.boolQuery();
- filterQueryBuilder.should(QueryBuilders.matchQuery("id", "1000"));
- request.setFilterBuilder(filterQueryBuilder);
-
- //3 分页及排序
- request.setQueryBuilder(boolQueryBuilder);
- Sort sort = Sort.by(Direction.DESC, "age");
- PageRequest pageRequest = PageRequest.of(0, 10, sort);
- request.setPageable(pageRequest);
-
- SearchHits<Student> hits = myEsService.search(Student.class, request);
- System.out.println(JSONObject.toJSONString(hits));
- }
- }
Kibanan安装比较简单,es集群搭建成功后,修改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"]
./bin/kibana
- # 是否支持跨域,es-header插件使用
- http.cors.enabled: true
- # *表示支持所有域名跨域访问
- http.cors.allow-origin: "*"
- http.cors.allow-headers: Authorization,X-Requested-With,Content-Type,Content-Length
http://localhost:9200/?auth_user=elastic&auth_password=elastic123
类别
|
优点
|
缺点
|
建议
|
nginx
|
对外屏蔽了ES集群的真实IP和端口,配置也较简单
|
只能做一些网络访问安全上面的防护,不能对索引及字段进行精确控制
|
选择X-pack
经验证在免费情况下X-Pack能满足基本诉求,对应用中使用影响也比较小
|
Search Guard
|
开源免费,基于RBAC权限模型设计,能够细粒度进行管控
|
配置复杂,需要安装证书及业务应用代码改造
| |
X-Pack
|
官方提供,基于RBAC权限模型设计,能够细粒度进行管控,与client api及es集群兼容性较好
|
配置稍复杂,基础部分功能免费
|
bin/elasticsearch-certutil ca
bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12
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.truststore.path: certs/elastic-certificates.p12
path.repo: ["/data/backups", "/data2/backups"]
curl -u elastic:elastic123 -X POST 'http://ip:9200/_snapshot/jingkai_backup/snapshot/_status'
PUT /_snapshot/backup1 { "type": "fs", "settings": { "location": "/data/backups", "compress": true, "max_snapshot_bytes_per_sec": "50mb", "max_restore_bytes_per_sec": "50mb" } }
PUT /_snapshot/backup1/snapshot_20221013?wait_for_completion=true { "indices": "index_1,index_2", "ignore_unavailable": true, "include_global_state": false }
GET /_snapshot/backup1/snapshot_20221013/_status
"indices": "index_1,index_2"
: 可以使用该参数只对部分索引进行备份
POST /_snapshot/backup1/snapshot_20221013/_restore { "indices": "index_1,index_2", "ignore_unavailable": true, "include_global_state": true, "rename_pattern": "index_(.+)", "rename_replacement": "restored_index_$1", "include_aliases": false }
indices
, 则表示恢复所有索引.
DELETE /_snapshot/backup1/snapshot_20221013
POST _reindex { "source": { "index": "app1_pay_order_index" }, "dest": { "index": "app1_pay_order_index_new" } }
POST /_aliases { "actions": [ #删除别名 { "remove": { "index": "app1_pay_order", "alias": "app1_pay_order2" } }, #添加别名 { "add": { "index": "app1_pay_order_new", "alias": "app1_pay_order2" }} ] }
GET _alias
GET app1_pay_order/_alias
- //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:elastic123 "http://127.0.0.1:9200/_cluster/health?pretty"
-
- //4.查询Es全局状态
- curl -XGET -u elastic:elastic123 "http://127.0.0.1:9200/_cluster/stats?pretty"
-
- //5.查询集群设置
- curl -XGET -u elastic:elastic123 "http://127.0.0.1:9200/_cluster/settings?pretty"
-
- //6.查询集群文档总数
- curl -XGET -u elastic:elastic123 "http://127.0.0.1:9200/_cat/count?v"
-
- //7.查看当前集群索引分片信息
- curl -XGET -u elastic:elastic123 "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’
kibana工具
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。