├── .gitignore ├── README.md ├── SUMMARY.md ├── assets ├── Cover_1600_2400.jpg ├── Cover_400_600.jpg ├── Cover_800_1200.jpg └── qrcode_for_gh_26893aa0a4ea_258.jpg ├── java-high-level-rest-client.md ├── java-high-level-rest-client ├── getting-started.md ├── getting-started │ ├── compatibility.md │ ├── dependencies.md │ ├── initialization.md │ ├── javadoc.md │ └── maven-repository.md ├── migration-guide.md ├── migration-guide │ ├── changing-the-applications-code.md │ ├── changing-the-clients-initialization-code.md │ ├── how-to-migrate.md │ ├── motivations-around-a-new-java-client.md │ ├── prerequisite.md │ ├── provide-feedback.md │ └── updating-the-dependencies.md ├── supported-apis.md ├── supported-apis │ ├── bulk-api.md │ ├── clear-scroll-api.md │ ├── delete-api.md │ ├── get-api.md │ ├── index-api.md │ ├── info-api.md │ ├── search-api.md │ ├── search-scroll-api.md │ └── update-api.md ├── using-java-builders.md └── using-java-builders │ ├── building-aggregations.md │ └── building-queries.md ├── java-low-level-rest-client.md ├── java-low-level-rest-client ├── common-configuration.md ├── common-configuration │ ├── basic-authentication.md │ ├── encrypted-communication.md │ ├── number-of-threads.md │ ├── others.md │ └── timeouts.md ├── getting-started.md ├── getting-started │ ├── dependencies.md │ ├── initialization.md │ ├── javadoc.md │ ├── logging.md │ ├── maven-repository.md │ ├── performing-requests.md │ ├── reading-responses.md │ └── shading.md ├── sniffer.md └── sniffer │ ├── javadoc.md │ ├── maven-repository.md │ └── usage.md └── overview.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Node rules: 2 | ## Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 3 | .grunt 4 | 5 | ## Dependency directory 6 | ## Commenting this out is preferred by some people, see 7 | ## https://docs.npmjs.com/misc/faq#should-i-check-my-node_modules-folder-into-git 8 | node_modules 9 | 10 | # Book build output 11 | _book 12 | 13 | # eBook build output 14 | *.epub 15 | *.mobi 16 | *.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Elasticsearch Java Rest API 手册 2 | 3 | ![](/assets/Cover_400_600.jpg) 4 | 5 | 本手册由 [全科](http://quanke.name) 翻译,并且整理成电子书,支持PDF,ePub,Mobi格式,方便大家下载阅读。 6 | 7 | 阅读地址:[https://es.quanke.name](https://es.quanke.name) 8 | 9 | 下载地址:[https://www.gitbook.com/book/quanke/elasticsearch-java-rest](https://www.gitbook.com/book/quanke/elasticsearch-java-rest) 10 | 11 | github地址:[https://github.com/quanke/elasticsearch-java-rest](https://github.com/quanke/elasticsearch-java-rest) 12 | 13 | gitee 地址:[https://gitee.com/quanke/elasticsearch-java-rest](https://gitee.com/quanke/elasticsearch-java-rest) 14 | 15 | 编辑:[http://quanke.name](http://quanke.name) 16 | 17 | 编辑整理辛苦,还望大神们点一下star ,抚平我虚荣的心 18 | 19 | > 不只是官方文档的翻译,还包含使用实例,包含我们使用踩过的坑 20 | 21 | 更多请关注我的微信公众号: 22 | 23 | ![](/assets/qrcode_for_gh_26893aa0a4ea_258.jpg) 24 | 25 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | * [Introduction](README.md) 4 | * [Overview](overview.md) 5 | * [Java Low Level REST Client](java-low-level-rest-client.md) 6 | * [Getting started](java-low-level-rest-client/getting-started.md) 7 | * [Javadoc](java-low-level-rest-client/getting-started/javadoc.md) 8 | * [Maven Repository](java-low-level-rest-client/getting-started/maven-repository.md) 9 | * [Dependencies](java-low-level-rest-client/getting-started/dependencies.md) 10 | * [Shading](java-low-level-rest-client/getting-started/shading.md) 11 | * [Initialization](java-low-level-rest-client/getting-started/initialization.md) 12 | * [Performing requests](java-low-level-rest-client/getting-started/performing-requests.md) 13 | * [Reading responses](java-low-level-rest-client/getting-started/reading-responses.md) 14 | * [Logging](java-low-level-rest-client/getting-started/logging.md) 15 | * [Common configuration](java-low-level-rest-client/common-configuration.md) 16 | * [Timeouts](java-low-level-rest-client/common-configuration/timeouts.md) 17 | * [Number of threads](java-low-level-rest-client/common-configuration/number-of-threads.md) 18 | * [Basic authentication](java-low-level-rest-client/common-configuration/basic-authentication.md) 19 | * [Encrypted communication](java-low-level-rest-client/common-configuration/encrypted-communication.md) 20 | * [Others](java-low-level-rest-client/common-configuration/others.md) 21 | * [Sniffer](java-low-level-rest-client/sniffer.md) 22 | * [Javadoc](java-low-level-rest-client/sniffer/javadoc.md) 23 | * [Maven Repository](java-low-level-rest-client/sniffer/maven-repository.md) 24 | * [Usage](java-low-level-rest-client/sniffer/usage.md) 25 | * [Java High Level REST Client](java-high-level-rest-client.md) 26 | * [Getting started](java-high-level-rest-client/getting-started.md) 27 | * [Compatibility](java-high-level-rest-client/getting-started/compatibility.md) 28 | * [Javadoc](java-high-level-rest-client/getting-started/javadoc.md) 29 | * [Maven Repository](java-high-level-rest-client/getting-started/maven-repository.md) 30 | * [Dependencies](java-high-level-rest-client/getting-started/dependencies.md) 31 | * [Initialization](java-high-level-rest-client/getting-started/initialization.md) 32 | * [Supported APIs](java-high-level-rest-client/supported-apis.md) 33 | * [Index API](java-high-level-rest-client/supported-apis/index-api.md) 34 | * [Get API](java-high-level-rest-client/supported-apis/get-api.md) 35 | * [Delete API](java-high-level-rest-client/supported-apis/delete-api.md) 36 | * [Update API](java-high-level-rest-client/supported-apis/update-api.md) 37 | * [Bulk API](java-high-level-rest-client/supported-apis/bulk-api.md) 38 | * [Search API](java-high-level-rest-client/supported-apis/search-api.md) 39 | * [Search Scroll API](java-high-level-rest-client/supported-apis/search-scroll-api.md) 40 | * [Clear Scroll API](java-high-level-rest-client/supported-apis/clear-scroll-api.md) 41 | * [Info API](java-high-level-rest-client/supported-apis/info-api.md) 42 | * [Using Java Builders](java-high-level-rest-client/using-java-builders.md) 43 | * [Building Queries](java-high-level-rest-client/using-java-builders/building-queries.md) 44 | * [Building Aggregations](java-high-level-rest-client/using-java-builders/building-aggregations.md) 45 | * [Migration Guide](java-high-level-rest-client/migration-guide.md) 46 | * [Motivations around a new Java client](java-high-level-rest-client/migration-guide/motivations-around-a-new-java-client.md) 47 | * [Prerequisite](java-high-level-rest-client/migration-guide/prerequisite.md) 48 | * [How to migrate](java-high-level-rest-client/migration-guide/how-to-migrate.md) 49 | * [Updating the dependencies](java-high-level-rest-client/migration-guide/updating-the-dependencies.md) 50 | * [Changing the client’s initialization code](java-high-level-rest-client/migration-guide/changing-the-clients-initialization-code.md) 51 | * [Changing the application’s code](java-high-level-rest-client/migration-guide/changing-the-applications-code.md) 52 | * [Provide feedback](java-high-level-rest-client/migration-guide/provide-feedback.md) 53 | 54 | -------------------------------------------------------------------------------- /assets/Cover_1600_2400.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quanke/elasticsearch-java-rest/c76f985ea7e8661a462259d5fb9c9a4b336728e5/assets/Cover_1600_2400.jpg -------------------------------------------------------------------------------- /assets/Cover_400_600.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quanke/elasticsearch-java-rest/c76f985ea7e8661a462259d5fb9c9a4b336728e5/assets/Cover_400_600.jpg -------------------------------------------------------------------------------- /assets/Cover_800_1200.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quanke/elasticsearch-java-rest/c76f985ea7e8661a462259d5fb9c9a4b336728e5/assets/Cover_800_1200.jpg -------------------------------------------------------------------------------- /assets/qrcode_for_gh_26893aa0a4ea_258.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quanke/elasticsearch-java-rest/c76f985ea7e8661a462259d5fb9c9a4b336728e5/assets/qrcode_for_gh_26893aa0a4ea_258.jpg -------------------------------------------------------------------------------- /java-high-level-rest-client.md: -------------------------------------------------------------------------------- 1 | 2 | # Java 高级 REST 客户端 3 | 4 | Java高级REST客户端可以在Java Low Level REST客户机之上工作。 其主要目标是公开特定方法的API,接受请求对象作为参数并返回响应对象,以便客户端自己处理请求编组和响应解组。 5 | 6 | 每个API可以同步或异步地调用。 同步方法返回一个响应对象,而名称以 `async` 后缀结尾的异步方法需要收到响应或错误后才会通知(在低级别客户端管理的线程池上)的侦听器参数。 7 | 8 | Java高级REST客户端依赖于 `Elasticsearch` 核心项目。 它接受与 `TransportClient` 相同的请求参数,并返回相同的响应对象。 9 | -------------------------------------------------------------------------------- /java-high-level-rest-client/getting-started.md: -------------------------------------------------------------------------------- 1 | # 起步 2 | 3 | 本节介绍了如何在应用程序中使用高级REST客户端。 -------------------------------------------------------------------------------- /java-high-level-rest-client/getting-started/compatibility.md: -------------------------------------------------------------------------------- 1 | # 兼容性 2 | 3 | Java高级REST客户端需要Java 1.8,并依赖于Elasticsearch核心项目。 客户端版本要与客户端开发的Elasticsearch版本相同。 它接受与 `TransportClient` 相同的请求参数,并返回相同的响应对象。 如果需要将应用程序从TransportClient迁移到新的REST客户端,请参阅 [`迁移指南`](https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-level-migration.html)。 4 | 5 | 高级客户端保证能够与运行在相同主版本和大于或等于次要版本的任何Elasticsearch节点进行通信。它不需要与它进行通信的弹性搜索节点相同的次要版本,因为它是向前兼容的,意味着它支持与之前开发的弹性搜索的更新版本进行通信。 6 | 7 | 5.6 客户端可以与任何 5.6.x Elasticsearch 节点进行通信。以前的 5.x 小版本,如 5.5.x,5.4.x 等不(完全)支持。 8 | 9 | 6.0 客户端能够与任何 6.x Elasticsearch 节点进行通信,而 6.1 客户端确实能够与 6.1,6.2 和以后的 6.x 版本进行通信,但与以前的 Elasticsearch 节点版本通信时可能会出现不兼容问题例如 6.1 到 6.0 之间,例如 6.1 客户端支持而 6.0 节点不知道的某些API的新请求主体字段。 10 | 11 | 建议在将Elasticsearch集群升级到新的主要版本时升级高级客户端,因为REST API突破性更改可能会导致意外的结果,具体取决于请求所击中的节点,新添加的API只能由较新版本的客户端。一旦群集中的所有节点都升级到新的主版本,则客户端应当更新。 -------------------------------------------------------------------------------- /java-high-level-rest-client/getting-started/dependencies.md: -------------------------------------------------------------------------------- 1 | # 依赖项 2 | 3 | 高级 Java REST Client 依赖以下包: 4 | 5 | - org.elasticsearch.client:elasticsearch-rest-client 6 | - org.elasticsearch:elasticsearch -------------------------------------------------------------------------------- /java-high-level-rest-client/getting-started/initialization.md: -------------------------------------------------------------------------------- 1 | # 初始化 2 | 3 | RestHighLevelClient 实例的构建需要一个 REST 低级客户端就像下面这样: 4 | 5 | ``` 6 | RestHighLevelClient client = 7 | new RestHighLevelClient(lowLevelRestClient); //lowLevelRestClient: 我们之前创建的 [REST低级客户端](https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-low-usage-initialization.html) 实例 8 | ``` 9 | 10 | 在本文档中关于Java高级客户端的的其余部分里,`RestHighLevelClient` 实例将以 `client` 被引用。 11 | -------------------------------------------------------------------------------- /java-high-level-rest-client/getting-started/javadoc.md: -------------------------------------------------------------------------------- 1 | # Javadoc 2 | 3 | https://artifacts.elastic.co/javadoc/org/elasticsearch/client/elasticsearch-rest-high-level-client/5.6.0/index.html 4 | -------------------------------------------------------------------------------- /java-high-level-rest-client/getting-started/maven-repository.md: -------------------------------------------------------------------------------- 1 | 2 | # Maven 仓库 3 | 4 | 高级 Java REST 客户端被托管在 Maven 中央仓库里。所需的最低Java版本为 1.8。 5 | 6 | 高级 REST 客户端与 elasticsearch 的发行周期相同。可以使用期望的版本进行替换。 7 | 8 | ## Maven 配置 9 | 10 | 若使用 Maven 作依赖管理,你可以这样配置依赖。将下列内容添加到你的 pom.xml 文件里: 11 | 12 | ``` 13 | 14 | org.elasticsearch.client 15 | elasticsearch-rest-high-level-client 16 | 5.6.0 17 | 18 | ``` 19 | 20 | ## Gradle 配置 21 | 22 | 若使用 gradle 作依赖管理,你可以这样配置依赖。将下列内容添加到你的 build.gradle 文件里: 23 | 24 | ``` 25 | dependencies { 26 | compile 'org.elasticsearch.client:elasticsearch-rest-high-level-client:5.6.0' 27 | } 28 | ``` -------------------------------------------------------------------------------- /java-high-level-rest-client/migration-guide.md: -------------------------------------------------------------------------------- 1 | 迁移指南 2 | 3 | 本节介绍如何将现有代码从 TransportClient 迁移到使用 Elasticsearch 5.6.0 版本发布的新的 Java 高级 REST 客户端。 4 | -------------------------------------------------------------------------------- /java-high-level-rest-client/migration-guide/changing-the-applications-code.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quanke/elasticsearch-java-rest/c76f985ea7e8661a462259d5fb9c9a4b336728e5/java-high-level-rest-client/migration-guide/changing-the-applications-code.md -------------------------------------------------------------------------------- /java-high-level-rest-client/migration-guide/changing-the-clients-initialization-code.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quanke/elasticsearch-java-rest/c76f985ea7e8661a462259d5fb9c9a4b336728e5/java-high-level-rest-client/migration-guide/changing-the-clients-initialization-code.md -------------------------------------------------------------------------------- /java-high-level-rest-client/migration-guide/how-to-migrate.md: -------------------------------------------------------------------------------- 1 | # 怎样合并 2 | 3 | 调整现有代码以使用RestHighLevelClient而不是TransportClient需要以下步骤: 4 | 5 | - 更新依赖关系 6 | - 更新客户端初始化 7 | - 更新应用程序代码 -------------------------------------------------------------------------------- /java-high-level-rest-client/migration-guide/motivations-around-a-new-java-client.md: -------------------------------------------------------------------------------- 1 | # 使用一个新的Java客户端的动机 2 | 3 | 自从第一次提交以来,现有的TransportClient已经成为Elasticsearch的一部分。 它是一个特殊的客户端,因为它使用传输协议与Elasticsearch进行通信,如果客户端的Elasticsearch实例与Elasticsearch实例的版本不同,则会导致兼容性问题。 4 | 5 | 我们在2016年发布了一个低级别的REST客户端,它基于众所周知的Apache HTTP客户端,并且允许在任何版本中使用HTTP与Elasticsearch集群进行通信。 最重要的是,我们发布了基于低级客户端的高级REST客户端,但是负责请求编组和响应解组。 6 | 7 | 如果您有兴趣了解更多关于这些变化的信息,我们写了一篇关于官方Elasticsearch Java客户端状态的博客文章。 -------------------------------------------------------------------------------- /java-high-level-rest-client/migration-guide/prerequisite.md: -------------------------------------------------------------------------------- 1 | # 条件 2 | 3 | Java 1.8 -------------------------------------------------------------------------------- /java-high-level-rest-client/migration-guide/provide-feedback.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quanke/elasticsearch-java-rest/c76f985ea7e8661a462259d5fb9c9a4b336728e5/java-high-level-rest-client/migration-guide/provide-feedback.md -------------------------------------------------------------------------------- /java-high-level-rest-client/migration-guide/updating-the-dependencies.md: -------------------------------------------------------------------------------- 1 | # 更新依赖 2 | 3 | 使用TransportClient的Java应用程序依赖于org.elasticsearch.client:transport artifact。 这个依赖关系必须被高级客户端的新依赖所取代。 4 | 5 | “入门”页面显示了Maven和Gradle的典型配置,并介绍了高级客户端提供的依赖关系。 -------------------------------------------------------------------------------- /java-high-level-rest-client/supported-apis.md: -------------------------------------------------------------------------------- 1 | 2 | # 支持的 API 3 | 4 | Java 高级 REST 客户端支持下列 API : 5 | 6 | 单一文档 API 7 | 8 | - [Index API](supported-apis/index-api.md) 9 | - [Get API](supported-apis/get-api.md) 10 | - [Delete API](supported-apis/delete-api.md) 11 | - [Update API](supported-apis/update-api.md) 12 | 13 | 多文档 API 14 | 15 | - [Bulk API](supported-apis/bulk-api.md) 16 | 17 | 搜索 API 18 | 19 | - [Search API](supported-apis/search-api.md) 20 | - [Search Scroll API](supported-apis/search-scroll-api.md) 21 | - [Clear Scroll API](supported-apis/clear-scroll-api.md) 22 | 23 | 各种 API 24 | 25 | - [Info API](supported-apis/info-api.md) -------------------------------------------------------------------------------- /java-high-level-rest-client/supported-apis/bulk-api.md: -------------------------------------------------------------------------------- 1 | 2 | # Bulk API 3 | 4 | 注意: Java高级REST客户端提供批量处理器来协助大量请求 5 | 6 | ## Bulk 请求 7 | 8 | BulkRequest 可以被用在使用单个请求执行多个 索引,更新 和/或 删除 操作的情况下。 9 | 10 | 它要求至少要一个操作被添加到 Bulk 请求上: 11 | 12 | ``` 13 | BulkRequest request = new BulkRequest(); // 创建 BulkRequest 14 | request.add(new IndexRequest("posts", "doc", "1") // 添加第一个 IndexRequest 到 Bulk 请求上, 参看 [Index API](https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-document-index.html) 获取更多关于如何构建 IndexRequest 的信息. 15 | .source(XContentType.JSON,"field", "foo")); 16 | request.add(new IndexRequest("posts", "doc", "2") // 添加第二个 IndexRequest 17 | .source(XContentType.JSON,"field", "bar")); 18 | request.add(new IndexRequest("posts", "doc", "3") // 添加第三个 IndexRequest 19 | .source(XContentType.JSON,"field", "baz")); 20 | ``` 21 | 22 | > 警告: Bulk API仅支持以JSON或SMILE编码的文档。 以任何其他格式提供文件将导致错误。 23 | 24 | 不同的操作类型也可以添加到同一个BulkRequest中: 25 | 26 | ``` 27 | BulkRequest request = new BulkRequest(); 28 | request.add(new DeleteRequest("posts", "doc", "3")); // 29 | Adds a DeleteRequest to the BulkRequest. See Delete API for more information on how to build DeleteRequest. 30 | request.add(new UpdateRequest("posts", "doc", "2") 31 | .doc(XContentType.JSON,"other", "test")); // 32 | Adds an UpdateRequest to the BulkRequest. See Update API for more information on how to build UpdateRequest. 33 | request.add(new IndexRequest("posts", "doc", "4") //Adds an IndexRequest using the SMILE format 34 | .source(XContentType.JSON,"field", "baz")); 35 | ``` 36 | 37 | ### 可选参数 38 | 39 | 提供下列可选参数: 40 | 41 | ``` 42 | request.timeout(TimeValue.timeValueMinutes(2)); 43 | request.timeout("2m"); 44 | Timeout to wait for the bulk request to be performed as a TimeValue 45 | Timeout to wait for the bulk request to be performed as a String 46 | request.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL); 47 | request.setRefreshPolicy("wait_for"); 48 | Refresh policy as a WriteRequest.RefreshPolicy instance 49 | Refresh policy as a String 50 | request.waitForActiveShards(2); 51 | request.waitForActiveShards(ActiveShardCount.ALL); 52 | Sets the number of shard copies that must be active before proceeding with the index/update/delete operations. 53 | Number of shard copies provided as a ActiveShardCount: can be ActiveShardCount.ALL, ActiveShardCount.ONE or ActiveShardCount.DEFAULT (default) 54 | ``` 55 | 56 | ### 同步执行 57 | 58 | ``` 59 | BulkResponse bulkResponse = client.bulk(request); 60 | ``` 61 | 62 | ### 异步执行 63 | 64 | ``` 65 | client.bulkAsync(request, new ActionListener() { 66 | @Override 67 | public void onResponse(BulkResponse bulkResponse) { 68 | //Called when the execution is successfully completed. The response is provided as an argument and contains a list of individual results for each operation that was executed. Note that one or more operations might have failed while the others have been successfully executed. 69 | } 70 | @Override 71 | public void onFailure(Exception e) { 72 | //Called when the whole BulkRequest fails. In this case the raised exception is provided as an argument and no operation has been executed. 73 | } 74 | }); 75 | ``` 76 | 77 | ## Bulk 响应 78 | 79 | 返回的BulkResponse包含有关执行操作的信息,并允许对每个结果进行迭代,如下所示: 80 | 81 | ``` 82 | for (BulkItemResponse bulkItemResponse : bulkResponse) { //迭代所有操作的结果 83 | DocWriteResponse itemResponse = bulkItemResponse.getResponse(); //Retrieve the response of the operation (successful or not), can be IndexResponse, UpdateResponse or DeleteResponse which can all be seen as DocWriteResponse instances 84 | if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.INDEX 85 | || bulkItemResponse.getOpType() == DocWriteRequest.OpType.CREATE) { 86 | // Handle the response of an index operation 87 | IndexResponse indexResponse = (IndexResponse) itemResponse; 88 | } else if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.UPDATE) { 89 | //Handle the response of a update operation 90 | UpdateResponse updateResponse = (UpdateResponse) itemResponse; 91 | } else if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.DELETE) { 92 | // Handle the response of a delete operation 93 | DeleteResponse deleteResponse = (DeleteResponse) itemResponse; 94 | } 95 | } 96 | ``` 97 | 批量响应提供了一种快速检查一个或多个操作是否失败的方法: 98 | 99 | ``` 100 | if (bulkResponse.hasFailures()) { // 只要有一个操作失败了,这个方法就返回 true 101 | } 102 | ``` 103 | 104 | 在这种情况下,有必要迭代所有运算结果,以检查操作是否失败,如果是,则检索相应的故障: 105 | 106 | ``` 107 | for (BulkItemResponse bulkItemResponse : bulkResponse) { 108 | if (bulkItemResponse.isFailed()) { //Indicate if a given operation failed 109 | BulkItemResponse.Failure failure = bulkItemResponse.getFailure(); //Retrieve the failure of the failed operation 110 | } 111 | } 112 | ``` 113 | 114 | ## Bulk 处理器 115 | 116 | BulkProcessor通过提供允许索引/更新/删除操作在添加到处理器时透明执行的实用程序类来简化Bulk API的使用。 117 | 118 | 为了执行请求,BulkProcessor需要3个组件: 119 | 120 | 121 | - RestHighLevelClient 122 | 123 | 这个客户端用来执行 BulkRequest 并接收 BulkResponse 。 124 | 125 | - BulkProcessor.Listener 126 | 127 | 这个监听器会在每个 BulkRequest 执行之前和之后被调用,或者当 BulkRequest 失败时调用。 128 | 129 | - ThreadPool 130 | 131 | BulkRequest执行是使用这个池的线程完成的,允许BulkProcessor以非阻塞的方式工作,并允许在批量请求执行的同时接受新的索引/更新/删除请求。 132 | 133 | 然后 BulkProcessor.Builder 类可以被用来构建新的 BulkProcessor : 134 | ``` 135 | ThreadPool threadPool = new ThreadPool(settings); // 使用已有的 Settings 对象创建 ThreadPool。 136 | BulkProcessor.Listener listener = new BulkProcessor.Listener() { // 创建 BulkProcessor.Listener 137 | @Override 138 | public void beforeBulk(long executionId, BulkRequest request) { 139 | //This method is called before each execution of a BulkRequest 140 | } 141 | @Override 142 | public void afterBulk(long executionId, BulkRequest request, BulkResponse response) { 143 | // This method is called after each execution of a BulkRequest 144 | } 145 | @Override 146 | public void afterBulk(long executionId, BulkRequest request, Throwable failure) { 147 | //This method is called when a BulkRequest failed 148 | } 149 | }; 150 | BulkProcessor bulkProcessor = new BulkProcessor.Builder(client::bulkAsync, listener, threadPool) 151 | .build(); // 通过调用 BulkProcessor.Builder 的 build() 方法创建 BulkProcessor。 RestHighLevelClient.bulkAsync() 将被用来执行 BulkRequest。 152 | ``` 153 | 154 | BulkProcessor.Builder 提供了方法来配置 BulkProcessor 应该如何处理请求的执行: 155 | 156 | ``` 157 | BulkProcessor.Builder builder = new BulkProcessor.Builder(client::bulkAsync, listener, threadPool); 158 | builder.setBulkActions(500); //Set when to flush a new bulk request based on the number of actions currently added (defaults to 1000, use -1 to disable it) 159 | builder.setBulkSize(new ByteSizeValue(1L, ByteSizeUnit.MB)); // Set when to flush a new bulk request based on the size of actions currently added (defaults to 5Mb, use -1 to disable it) 160 | builder.setConcurrentRequests(0); //Set the number of concurrent requests allowed to be executed (default to 1, use 0 to only allow the execution of a single request) 161 | builder.setFlushInterval(TimeValue.timeValueSeconds(10L)); // Set a flush interval flushing any BulkRequest pending if the interval passes (defaults to not set) 162 | builder.setBackoffPolicy(BackoffPolicy.constantBackoff(TimeValue.timeValueSeconds(1L), 3)); //Set a constant back off policy that initially waits for 1 second and retries up to 3 times. See BackoffPolicy.noBackoff(), BackoffPolicy.constantBackoff() and BackoffPolicy.exponentialBackoff() for more options. 163 | ``` 164 | 一旦创建了BulkProcessor,可以向其添加请求: 165 | 166 | ``` 167 | IndexRequest one = new IndexRequest("posts", "doc", "1"). 168 | source(XContentType.JSON, "title", "In which order are my Elasticsearch queries executed?"); 169 | IndexRequest two = new IndexRequest("posts", "doc", "2") 170 | .source(XContentType.JSON, "title", "Current status and upcoming changes in Elasticsearch"); 171 | IndexRequest three = new IndexRequest("posts", "doc", "3") 172 | .source(XContentType.JSON, "title", "The Future of Federated Search in Elasticsearch"); 173 | bulkProcessor.add(one); 174 | bulkProcessor.add(two); 175 | bulkProcessor.add(three); 176 | ``` 177 | 178 | 这些请求将由 BulkProcessor 执行,它负责为每个批量请求调用 BulkProcessor.Listener 。 179 | 监听器提供方法接收 BulkResponse 和 BulkResponse : 180 | 181 | ``` 182 | BulkProcessor.Listener listener = new BulkProcessor.Listener() { 183 | @Override 184 | public void beforeBulk(long executionId, BulkRequest request) { 185 | int numberOfActions = request.numberOfActions(); //Called before each execution of a BulkRequest, this method allows to know the number of operations that are going to be executed within the BulkRequest 186 | logger.debug("Executing bulk [{}] with {} requests", executionId, numberOfActions); 187 | } 188 | @Override 189 | public void afterBulk(long executionId, BulkRequest request, BulkResponse response) { 190 | if (response.hasFailures()) { 191 | //在每个 BulkRequest 执行之后调用,此方法允许获知 BulkResponse 是否包含错误 192 | logger.warn("Bulk [{}] executed with failures", executionId); 193 | } else { 194 | logger.debug("Bulk [{}] completed in {} milliseconds", executionId, response.getTook().getMillis()); 195 | } 196 | } 197 | @Override 198 | public void afterBulk(long executionId, BulkRequest request, Throwable failure) { 199 | logger.error("Failed to execute bulk", failure); //如果 BulkRequest 执行失败则调用,此方法可获知失败情况。 200 | } 201 | }; 202 | ``` 203 | 一旦将所有请求都添加到BulkProcessor,其实例需要使用两种可用的关闭方法之一关闭。 204 | 205 | 一旦所有请求都被添加到了 BulkProcessor, 它的实例就需要使用两种可用的关闭方法之一进行关闭。 206 | 207 | awaitClose() 可以被用来等待到所有请求都被处理,或者到指定的等待时间: 208 | 209 | ``` 210 | boolean terminated = bulkProcessor.awaitClose(30L, TimeUnit.SECONDS); 211 | ``` 212 | 213 | 如果所有批量请求完成,则该方法返回 true ,如果在完成所有批量请求之前等待时间过长,则返回 false 。 214 | 215 | close() 方法可以被用来立即关闭 BulkProcessor : 216 | 217 | ``` 218 | bulkProcessor.close(); 219 | ``` 220 | 221 | 在关闭处理器之前,两个方法都会刷新已经被天教导处理器的请求,并禁止添加任何新的请求。 222 | -------------------------------------------------------------------------------- /java-high-level-rest-client/supported-apis/clear-scroll-api.md: -------------------------------------------------------------------------------- 1 | 2 | # Clear Scroll API 3 | 4 | 使用 Search Scroll API 的搜索上下文在超过滚动时间时,会自动清除。但是,建议当不再需要使用 Clear Scroll API 后尽可能快的释放搜索上下文。 5 | 6 | ## Clear Scroll 请求 7 | 8 | ClearScrollRequest 可以像如下方式创建: 9 | 10 | ``` 11 | ClearScrollRequest request = new ClearScrollRequest(); // 创建一个新的 ClearScrollRequest 12 | request.addScrollId(scrollId); // 添加一个滚动id到要清除的滚动标志列表里 13 | https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-clear-scroll.html 14 | ``` -------------------------------------------------------------------------------- /java-high-level-rest-client/supported-apis/delete-api.md: -------------------------------------------------------------------------------- 1 | 2 | # Delete API 3 | 4 | ## 删除请求对象 5 | 6 | DeleteRequest 需要下列参数: 7 | 8 | ``` 9 | DeleteRequest request = new DeleteRequest( 10 | "posts", // index 11 | "doc", //Type 12 | "1"); // Document id 13 | 14 | ``` 15 | 可选参数 16 | 17 | ## 提供下列可选参数: 18 | 19 | ``` 20 | request.routing("routing"); // 路由值 21 | request.parent("parent"); //Parent 值 22 | request.timeout(TimeValue.timeValueMinutes(2)); // TimeValue 类型的等待主分片可用的超时时间 23 | request.timeout("2m"); // 字符串类型的等待主分片可用的超时时间 24 | request.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL); // Refresh policy as a WriteRequest.RefreshPolicy instance 25 | request.setRefreshPolicy("wait_for"); // Refresh policy as a String 26 | request.version(2); // Version 27 | request.versionType(VersionType.EXTERNAL); // Version type 28 | ``` 29 | 30 | ## 同步执行 31 | 32 | ``` 33 | DeleteResponse deleteResponse = client.delete(request); 34 | ``` 35 | 36 | ## 异步执行 37 | 38 | ``` 39 | client.deleteAsync(request, new ActionListener() { 40 | @Override 41 | public void onResponse(DeleteResponse deleteResponse) { 42 | //Called when the execution is successfully completed. The response is provided as an argument 43 | } 44 | @Override 45 | public void onFailure(Exception e) { 46 | //Called in case of failure. The raised exception is provided as an argument 47 | } 48 | }); 49 | ``` 50 | 51 | ## 删除操作的响应 52 | 53 | 返回的 DeleteResponse 对象允许通过执行以下操作获取相关信息: 54 | 55 | ``` 56 | String index = deleteResponse.getIndex(); 57 | String type = deleteResponse.getType(); 58 | String id = deleteResponse.getId(); 59 | long version = deleteResponse.getVersion(); 60 | ReplicationResponse.ShardInfo shardInfo = deleteResponse.getShardInfo(); 61 | if (shardInfo.getTotal() != shardInfo.getSuccessful()) { 62 | // Handle the situation where number of successful shards is less than total shards 63 | } 64 | if (shardInfo.getFailed() > 0) { 65 | for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) { 66 | String reason = failure.reason(); // Handle the potential failures 67 | } 68 | } 69 | ``` 70 | 也可以检查文档是否被发现: 71 | 72 | ``` 73 | DeleteRequest request = new DeleteRequest("posts", "doc", "does_not_exist"); 74 | DeleteResponse deleteResponse = client.delete(request); 75 | if (deleteResponse.getResult() == DocWriteResponse.Result.NOT_FOUND) { 76 | //如果被删除的文档没有被找到,做某些操作 77 | } 78 | ``` 79 | 80 | 如果有版本冲突,将抛出 ElasticsearchException 异常信息: 81 | 82 | ``` 83 | try { 84 | DeleteRequest request = new DeleteRequest("posts", "doc", "1").version(2); 85 | DeleteResponse deleteResponse = client.delete(request); 86 | } catch (ElasticsearchException exception) { 87 | if (exception.status() == RestStatus.CONFLICT) { 88 | //由于版本冲突错误导致的异常 89 | } 90 | } 91 | ``` -------------------------------------------------------------------------------- /java-high-level-rest-client/supported-apis/get-api.md: -------------------------------------------------------------------------------- 1 | 2 | # Get API 3 | 4 | ## 获取请求对象 5 | 6 | GetRequest 需要以下参数: 7 | 8 | ``` 9 | GetRequest getRequest = new GetRequest( 10 | "posts", // 索引 11 | "doc", // 类别 12 | "1"); // 文档id 13 | ``` 14 | 15 | ### 可选参数 16 | 17 | 提供以下可选参数: 18 | 19 | ``` 20 | request.fetchSourceContext(new FetchSourceContext(false)); //禁用检索源,默认为启用 21 | 22 | ``` 23 | String[] includes = new String[]{"message", "*Date"}; 24 | String[] excludes = Strings.EMPTY_ARRAY; 25 | FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes); 26 | request.fetchSourceContext(fetchSourceContext); //设置源包含的特定域 27 | 28 | ``` 29 | 30 | 31 | 32 | ``` 33 | String[] includes = Strings.EMPTY_ARRAY; 34 | String[] excludes = new String[]{"message"}; 35 | FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes); 36 | request.fetchSourceContext(fetchSourceContext); 37 | Configure source exclusion for specific fields 38 | ``` 39 | 40 | ``` 41 | request.storedFields("message"); //Configure retrieval for specific stored fields (requires fields to be stored separately in the mappings) 42 | GetResponse getResponse = client.get(request); 43 | String message = (String) getResponse.getField("message").getValue(); //Retrieve the message stored field (requires the field to be stored separately in the mappings) 44 | ``` 45 | ``` 46 | request.routing("routing"); //Routing value 47 | request.parent("parent"); //Parent value 48 | request.preference("preference"); //Preference value 49 | request.realtime(false); //Set realtime flag to false (true by default) 50 | request.refresh(true); //Perform a refresh before retrieving the document (false by default) 51 | request.version(2); //Version 52 | request.versionType(VersionType.EXTERNAL); //Version type 53 | ``` 54 | 55 | ### 同步执行 56 | 57 | ``` 58 | GetResponse getResponse = client.get(getRequest); 59 | ``` 60 | 61 | ### 异步执行 62 | 63 | ``` 64 | client.getAsync(request, new ActionListener() { 65 | @Override 66 | public void onResponse(GetResponse getResponse) { 67 | //Called when the execution is successfully completed. The response is provided as an argument. 68 | } 69 | @Override 70 | public void onFailure(Exception e) { 71 | //Called in case of failure. The raised exception is provided as an argument. 72 | } 73 | }); 74 | ``` 75 | 76 | ## 获取响应 77 | 78 | The returned GetResponse allows to retrieve the requested document along with its metadata and eventually stored fields. 79 | 80 | ``` 81 | String index = getResponse.getIndex(); 82 | String type = getResponse.getType(); 83 | String id = getResponse.getId(); 84 | if (getResponse.isExists()) { 85 | long version = getResponse.getVersion(); 86 | String sourceAsString = getResponse.getSourceAsString(); //Retrieve the document as a String 87 | Map sourceAsMap = getResponse.getSourceAsMap(); //Retrieve the document as a Map 88 | byte[] sourceAsBytes = getResponse.getSourceAsBytes(); //Retrieve the document as a byte[] 89 | } else { 90 | //Handle the scenario where the document was not found. Note that although the returned response has 404 status code, a valid GetResponse is returned rather than an exception thrown. Such response does not hold any source document and its isExists method returns false. 91 | } 92 | ``` 93 | 94 | 当针对不存在的索引执行获取请求时,响应有404状态码,抛出一个 ElasticsearchException 异常,需要如下处理: 95 | 96 | ``` 97 | GetRequest request = new GetRequest("does_not_exist", "doc", "1"); 98 | try { 99 | GetResponse getResponse = client.get(request); 100 | } catch (ElasticsearchException e) { 101 | if (e.status() == RestStatus.NOT_FOUND) { 102 | // 处理因为索引不存在而抛出的异常, 103 | } 104 | } 105 | ``` 106 | 107 | 如果请求了特定文档版本,但现有文档具有不同的版本号,则会引发版本冲突: 108 | 109 | ``` 110 | try { 111 | GetRequest request = new GetRequest("posts", "doc", "1").version(2); 112 | GetResponse getResponse = client.get(request); 113 | } catch (ElasticsearchException exception) { 114 | if (exception.status() == RestStatus.CONFLICT) { 115 | //表示返回了版本冲突错误引发异常 116 | } 117 | } 118 | ``` -------------------------------------------------------------------------------- /java-high-level-rest-client/supported-apis/index-api.md: -------------------------------------------------------------------------------- 1 | # Index API 2 | 3 | ## Index 请求 4 | 5 | IndexRequest 要求下列参数: 6 | 7 | ``` 8 | IndexRequest request = new IndexRequest( 9 | "posts", //Index 10 | "doc", //Type 11 | "1"); //Document id 12 | String jsonString = "{" + 13 | "\"user\":\"kimchy\"," + 14 | "\"postDate\":\"2013-01-30\"," + 15 | "\"message\":\"trying out Elasticsearch\"" + 16 | "}"; 17 | request.source(jsonString, XContentType.JSON); /以字符串提供的 Document source 18 | ``` 19 | 20 | ### 文档来源 21 | 22 | 文件来源可以以不同的方式提供: 23 | 24 | ``` 25 | Map jsonMap = new HashMap<>(); 26 | jsonMap.put("user", "kimchy"); 27 | jsonMap.put("postDate", new Date()); 28 | jsonMap.put("message", "trying out Elasticsearch"); 29 | IndexRequest indexRequest = new IndexRequest("posts", "doc", "1").source(jsonMap); //Map 作为文档源,它可以自动转换为 JSON 格式。 30 | ``` 31 | 32 | ``` 33 | XContentBuilder builder = XContentFactory.jsonBuilder(); 34 | builder.startObject(); 35 | { 36 | builder.field("user", "kimchy"); 37 | builder.field("postDate", new Date()); 38 | builder.field("message", "trying out Elasticsearch"); 39 | } 40 | builder.endObject(); 41 | IndexRequest indexRequest = new IndexRequest("posts", "doc", "1").source(builder); //XContentBuilder 对象作为文档源,由 Elasticsearch 内置的帮助器生成 JSON 内容 42 | 43 | ``` 44 | 45 | ``` 46 | IndexRequest indexRequest = new IndexRequest("posts", "doc", "1") 47 | .source("user", "kimchy", 48 | "postDate", new Date(), 49 | "message", "trying out Elasticsearch"); //以键值对对象作为文档来源,它自动转换为 JSON 格式 50 | ``` 51 | 52 | ### 可选参数 53 | 54 | 下列参数可选: 55 | 56 | ``` 57 | request.routing("routing"); //Routing 值 58 | ``` 59 | 60 | ``` 61 | request.parent("parent"); //Parent 值 62 | ``` 63 | 64 | ``` 65 | request.timeout(TimeValue.timeValueSeconds(1)); //`TimeValue`类型的等待主分片可用的超时时间 66 | request.timeout("1s"); //`String` 类型的等待主分片可用的超时时间 67 | ``` 68 | 69 | ``` 70 | request.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL); //以 WriteRequest.RefreshPolicy 实例的刷新策略参数 71 | request.setRefreshPolicy("wait_for"); // 字符串刷新策略参数 72 | ``` 73 | 74 | ``` 75 | request.version(2); //版本 76 | ``` 77 | 78 | ``` 79 | request.versionType(VersionType.EXTERNAL); //版本类型 80 | ``` 81 | 82 | ``` 83 | request.opType(DocWriteRequest.OpType.CREATE); //提供一个 DocWriteRequest.OpType 值作为操作类型 84 | request.opType("create"); //字符串类型的操作类型参数: 可以是 create 或 update (默认值) 85 | ``` 86 | 87 | ``` 88 | request.setPipeline("pipeline"); //在索引文档之前要执行的摄取管道的名称 89 | ``` 90 | ### 同步执行 91 | 92 | ``` 93 | IndexResponse indexResponse = client.index(request); 94 | ``` 95 | 96 | ### 异步执行 97 | 98 | ``` 99 | client.indexAsync(request, new ActionListener() { 100 | @Override 101 | public void onResponse(IndexResponse indexResponse) { 102 | //当操作成功完成的时候被调用。响应对象以参数的形式传入。 103 | } 104 | @Override 105 | public void onFailure(Exception e) { 106 | //故障时被调用。异常对象以参数的形式传入 107 | } 108 | }); 109 | ``` 110 | ## Index 响应 111 | 112 | 返回的“IndexResponse”可以检索有关执行操作的信息,如下所示: 113 | 114 | ``` 115 | String index = indexResponse.getIndex(); 116 | String type = indexResponse.getType(); 117 | String id = indexResponse.getId(); 118 | long version = indexResponse.getVersion(); 119 | if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) { 120 | //处理(如果需要)首次创建文档的情况 121 | } else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) { 122 | //处理(如果需要)文档已经存在时被覆盖的情况 123 | } 124 | ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo(); 125 | if (shardInfo.getTotal() != shardInfo.getSuccessful()) { 126 | //处理成功碎片数少于总碎片的情况 127 | } 128 | if (shardInfo.getFailed() > 0) { 129 | for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) { 130 | String reason = failure.reason();//处理潜在的故障 131 | } 132 | } 133 | ``` 134 | 135 | 如果存在版本冲突,将抛出 ElasticsearchException : 136 | 137 | ``` 138 | IndexRequest request = new IndexRequest("posts", "doc", "1") 139 | .source("field", "value") 140 | .version(1); 141 | try { 142 | IndexResponse response = client.index(request); 143 | } catch(ElasticsearchException e) { 144 | if (e.status() == RestStatus.CONFLICT) { 145 | //表示是由于返回了版本冲突错误引发的异常 146 | } 147 | } 148 | ``` 149 | 150 | 发生同样的情况发生在opType设置为create但是已经存在具有相同索引,类型和id的文档时: 151 | 152 | ``` 153 | IndexRequest request = new IndexRequest("posts", "doc", "1") 154 | .source("field", "value") 155 | .opType(DocWriteRequest.OpType.CREATE); 156 | try { 157 | IndexResponse response = client.index(request); 158 | } catch(ElasticsearchException e) { 159 | if (e.status() == RestStatus.CONFLICT) { 160 | //表示由于返回了版本冲突错误引发的异常 161 | } 162 | } 163 | ``` -------------------------------------------------------------------------------- /java-high-level-rest-client/supported-apis/info-api.md: -------------------------------------------------------------------------------- 1 | 2 | # Info API 3 | 4 | ## 执行 5 | 6 | 集群信息可以通过 info() 方法被获取到: 7 | 8 | ``` 9 | MainResponse response = client.info(); 10 | ``` 11 | ## 响应 12 | 13 | 返回的 MainResponse 提供了有关集群的各种信息: 14 | 15 | ``` 16 | ClusterName clusterName = response.getClusterName(); // 获取包含集群名称信息的 ClusterName 对象 17 | String clusterUuid = response.getClusterUuid(); // 获取集群的唯一标识符 18 | String nodeName = response.getNodeName(); // 获取执行请求的节点的名称 19 | Version version = response.getVersion(); // 获取已执行请求的节点版本 20 | Build build = response.getBuild(); // 获取已执行请求的节点的构建信息 21 | ``` -------------------------------------------------------------------------------- /java-high-level-rest-client/supported-apis/search-api.md: -------------------------------------------------------------------------------- 1 | 2 | # Search API 3 | 4 | ## 搜索请求 5 | 6 | SearchRequest用于与搜索文档,聚合,建议有关的任何操作,并且还提供了在生成的文档上请求突出显示的方法。 7 | 在最基本的形式中,我们可以向请求添加一个查询: 8 | 9 | ``` 10 | SearchRequest searchRequest = new SearchRequest(); //穿件SeachRequest,Without arguments this runs against all indices. 11 | SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();// 大多数的搜索参数被添加到 SearchSourceBuilder 。它为每个进入请求体的每个东西都提供 setter 方法。 12 | searchSourceBuilder.query(QueryBuilders.matchAllQuery()); // 添加一个 match_all 查询到 searchSourceBuilder 。 13 | 14 | ``` 15 | 16 | ### 可选参数 17 | 18 | 我们先看一下SearchRequest的一些可选参数: 19 | 20 | ``` 21 | SearchRequest searchRequest = new SearchRequest("posts"); // 限制请求到某个索引上 22 | searchRequest.types("doc"); // 限制请求的类别 23 | ``` 24 | 25 | 还有一些其他有趣的可选参数: 26 | 27 | ``` 28 | searchRequest.routing("routing"); // 设置路由参数、 29 | searchRequest.indicesOptions(IndicesOptions.lenientExpandOpen()); // 设置IndicesOptions控制如何解析不可用索引以及扩展通配符表达式 30 | searchRequest.preference("_local"); //使用首选参数,例如,执行搜索优先选择本地分片。 默认值是随机化分片。 31 | ``` 32 | 33 | ### 使用 SearchSourceBuilder 34 | 35 | 可以在SearchSourceBuilder上设置大多数控制搜索行为的选项,其中包含或多或少相当于 Rest API 的搜索请求正文中的选项。 36 | 37 | 以下是一些常见选项的示例: 38 | 39 | ``` 40 | SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); //使用默认选项创建 SearchSourceBuilder 。 41 | sourceBuilder.query(QueryBuilders.termQuery("user", "kimchy")); //设置查询对象。可以使任何类型的 QueryBuilder 42 | sourceBuilder.from(0); //设置from选项,确定要开始搜索的结果索引。 默认为0。 43 | sourceBuilder.size(5); //设置大小选项,确定要返回的搜索匹配数。 默认为10。 44 | sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); //设置一个可选的超时时间,用于控制搜索允许的时间。 45 | ``` 46 | 47 | 构建查询 48 | 49 | 搜索查询可以使用 QueryBuilder 对象创建。 对于Elasticsearch的 Query DSL 支持的每个搜索查询类型,都存在QueryBuilder。 50 | QueryBuilder 可以使用它的构造器创建: 51 | 52 | ``` 53 | //创建一个字段“user”与文本“kimchy”相匹配的的全文匹配查询。 54 | MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("user", "kimchy"); 55 | ``` 56 | 57 | 创建后,QueryBuilder对象提供了配置搜索查询选项的方法: 58 | 59 | ``` 60 | matchQueryBuilder.fuzziness(Fuzziness.AUTO); //在匹配查询上启用模糊匹配 61 | matchQueryBuilder.prefixLength(3); //在匹配查询上设置前缀长度 62 | matchQueryBuilder.maxExpansions(10); //设置最大扩展选项以控制查询的模糊过程 63 | 64 | ``` 65 | 66 | QueryBuilder 对象也可以使用 QueryBuilders 工具类创建。这个类提供了使用链式编程风格的辅助方法来创建 QueryBuilder 对象: 67 | 68 | ``` 69 | QueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("user", "kimchy") 70 | .fuzziness(Fuzziness.AUTO) 71 | .prefixLength(3) 72 | .maxExpansions(10); 73 | 74 | ``` 75 | 76 | 无论用于创建它的方法如何, QueryBuilder 对象必须添加到 SearchSourceBuilder 中,如下所示: 77 | 78 | ``` 79 | searchSourceBuilder.query(matchQueryBuilder); 80 | ``` 81 | 82 | “构建查询”页面列出了所有可用的搜索查询及其对应的QueryBuilder对象和QueryBuilders辅助方法。 83 | 84 | ### 指定排序 85 | 86 | SearchSourceBuilder允许添加一个或多个SortBuilder实例。 有四个特殊的实现(Field-,Score-,GeoDistance-和ScriptSortBuilder)。 87 | 88 | ``` 89 | sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC)); // 按_score降序排序(默认值) 90 | sourceBuilder.sort(new FieldSortBuilder("_uid").order(SortOrder.ASC)); //也按_id字段排序升序 91 | ``` 92 | 93 | 源过滤 94 | 95 | 96 | 默认情况下,搜索请求返回文档的内容,_source但像 Rest API 中的内容一样,您可以覆盖此行为。例如,您可以完全关闭 _source 检索: 97 | 98 | ``` 99 | sourceBuilder.fetchSource(false); 100 | ``` 101 | 102 | 该方法还接受一个或多个通配符模式的数组,以便以更精细的方式控制哪些字段包含或排除: 103 | 104 | ``` 105 | String[] includeFields = new String[] {"title", "user", "innerObject.*"}; 106 | String[] excludeFields = new String[] {"_type"}; 107 | sourceBuilder.fetchSource(includeFields, excludeFields); 108 | ``` 109 | 110 | ### 请求高亮 111 | 112 | 突出显示搜索结果可以通过设置来实现HighlightBuilder的 SearchSourceBuilder。可以通过向HighlightBuilder.Fielda 添加一个或多个实例来为每个字段定义不同的突出显示行为HighlightBuilder。 113 | 114 | ``` 115 | SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); 116 | HighlightBuilder highlightBuilder = new HighlightBuilder();//Creates a new HighlightBuilder 117 | HighlightBuilder.Field highlightTitle = 118 | new HighlightBuilder.Field("title");//Create a field highlighter for the title field 119 | highlightTitle.highlighterType("unified"); //Set the field highlighter type 120 | highlightBuilder.field(highlightTitle); //Add the field highlighter to the highlight builder 121 | HighlightBuilder.Field highlightUser = new HighlightBuilder.Field("user"); 122 | highlightBuilder.field(highlightUser); 123 | searchSourceBuilder.highlighter(highlightBuilder); 124 | ``` 125 | 126 | 有很多选项,这在Rest API文档中有详细的介绍。Rest API参数(例如,pre_tags)通常由具有相似名称的 setter(例如#preTags(String …))更改。 127 | 128 | 随后可以从 SearchResponse 中检索突出显示的文本片段。 129 | 130 | ### 请求聚合 131 | 132 | 可以通过首先创建适当的集合AggregationBuilder然后在其上设置集合来将搜索添加到搜索结果中 SearchSourceBuilder。在下面的示例中,我们terms在公司名称上创建一个聚合,其中包含公司员工平均年龄的子聚合: 133 | 134 | ``` 135 | SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); 136 | TermsAggregationBuilder aggregation = AggregationBuilders.terms("by_company") 137 | .field("company.keyword"); 138 | aggregation.subAggregation(AggregationBuilders.avg("average_age") 139 | .field("age")); 140 | searchSourceBuilder.aggregation(aggregation); 141 | ``` 142 | 143 | “ 构建聚合”页面提供了所有可用聚合以及其相应AggregationBuilder对象和AggregationBuilders帮助方法的列表。 144 | 145 | 后面我们将看到如何访问聚合的 SearchResponse。 146 | 147 | ### 请求建议 148 | 149 | 要向搜索请求添加建议,请使用SuggestionBuilder从SuggestBuilders工厂类轻松访问的其中一个实现。建议构建者需要添加到顶层SuggestBuilder,本身可以设置在 顶层SearchSourceBuilder。 150 | 151 | ``` 152 | SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); 153 | SuggestionBuilder termSuggestionBuilder = 154 | SuggestBuilders.termSuggestion("user").text("kmichy"); // 155 | Creates a new TermSuggestionBuilder for the user field and the text kmichy 156 | SuggestBuilder suggestBuilder = new SuggestBuilder(); 157 | suggestBuilder.addSuggestion("suggest_user", termSuggestionBuilder); //Adds the suggestion builder and names it suggest_user 158 | searchSourceBuilder.suggest(suggestBuilder); 159 | ``` 160 | 161 | 后面我们将看到如何从 SearchResponse 获取建议。 162 | 163 | ### 自定义查询和聚合 164 | 165 | 该配置文件API可用于简档查询和聚集的执行针对特定搜索请求。为了使用它,配置文件标志必须设置为true SearchSourceBuilder: 166 | 167 | ``` 168 | SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); 169 | searchSourceBuilder.profile(true); 170 | ``` 171 | 172 | 一旦SearchRequest执行,相应的SearchResponse将 包含分析结果。 173 | 174 | ### 同步执行 175 | 176 | SearchRequest以下列方式执行时,客户端SearchResponse在继续执行代码之前等待返回: 177 | 178 | ``` 179 | SearchResponse searchResponse = client.search(searchRequest); 180 | ``` 181 | 182 | ### 异步执行 183 | 184 | ``` 185 | client.searchAsync(searchRequest, new ActionListener() { 186 | @Override 187 | public void onResponse(SearchResponse searchResponse) { 188 | //执行成功完成时调用。 189 | } 190 | @Override 191 | public void onFailure(Exception e) { 192 | //当整个SearchRequest失败时调用。 193 | } 194 | }); 195 | ``` 196 | ## 搜索响应 197 | 198 | 通过执行搜索返回的 SearchResponse 提供了关于搜索执行本身以及对返回的文档的访问的详细信息。 首先,有关于请求执行本身的有用信息,如HTTP状态代码,执行时间或请求提前终止或超时: 199 | 200 | ``` 201 | RestStatus status = searchResponse.status(); 202 | TimeValue took = searchResponse.getTook(); 203 | Boolean terminatedEarly = searchResponse.isTerminatedEarly(); 204 | boolean timedOut = searchResponse.isTimedOut(); 205 | ``` 206 | 207 | 其次,响应还通过提供关于搜索影响的分片总数以及成功与不成功的分片的统计信息,提供关于分片级别执行的信息。 可能的故障也可以通过遍历ShardSearchFailures上的数组进行迭代来处理,如下例所示: 208 | 209 | ``` 210 | int totalShards = searchResponse.getTotalShards(); 211 | int successfulShards = searchResponse.getSuccessfulShards(); 212 | int failedShards = searchResponse.getFailedShards(); 213 | for (ShardSearchFailure failure : searchResponse.getShardFailures()) { 214 | // 故障应该在这里被处理 215 | } 216 | ``` 217 | 218 | ### 检索 SearchHits 219 | 220 | 要访问返回的文档,我们需要首先得到响应中包含的 SearchHits : 221 | 222 | ``` 223 | SearchHits hits = searchResponse.getHits(); 224 | ``` 225 | 226 | 将SearchHits提供命中的所有全局信息,比如命中总数或最大分数: 227 | 228 | ``` 229 | long totalHits = hits.getTotalHits(); 230 | float maxScore = hits.getMaxScore(); 231 | ``` 232 | 233 | 嵌套在 SearchHits 的各个搜索结果可以被迭代访问: 234 | 235 | ``` 236 | SearchHit[] searchHits = hits.getHits(); 237 | for (SearchHit hit : searchHits) { 238 | // do something with the SearchHit 239 | } 240 | ``` 241 | 242 | SearchHit可以访问基本信息,如索引,类型,文档ID 以及每个搜索匹配的分数: 243 | 244 | ``` 245 | String index = hit.getIndex(); 246 | String type = hit.getType(); 247 | String id = hit.getId(); 248 | float score = hit.getScore(); 249 | ``` 250 | 251 | 此外,它可以让您将文档源作为简单的JSON-String或键/值对的映射。 在该映射中,字段名为键,含字段值为值。 多值字段作为对象的列表返回,嵌套对象作为另一个键/值映射。 这些情况需要相应地执行: 252 | 253 | ``` 254 | String sourceAsString = hit.getSourceAsString(); 255 | Map sourceAsMap = hit.getSourceAsMap(); 256 | String documentTitle = (String) sourceAsMap.get("title"); 257 | List users = (List) sourceAsMap.get("user"); 258 | Map innerObject = (Map) sourceAsMap.get("innerObject"); 259 | Retrieving Highlighting 260 | ``` 261 | 262 | 如果请求,可以从SearchHit结果中的每一个中检索突出显示的文本片段。命中对象提供对HighlightField实例的字段名称映射的访问,每个实例都包含一个或多个突出显示的文本片段: 263 | 264 | ``` 265 | SearchHits hits = searchResponse.getHits(); 266 | for (SearchHit hit : hits.getHits()) { 267 | Map highlightFields = hit.getHighlightFields(); 268 | HighlightField highlight = highlightFields.get("title"); //获取该title领域 的突出显示 269 | Text[] fragments = highlight.fragments(); //获取包含突出显示的字段内容的一个或多个片段 270 | String fragmentString = fragments[0].string(); 271 | } 272 | ``` 273 | 274 | ### 检索聚合 275 | 276 | 可以SearchResponse通过首先获取聚合树的根,Aggregations对象,然后通过名称获取聚合来检索聚合。 277 | 278 | ``` 279 | Aggregations aggregations = searchResponse.getAggregations(); 280 | Terms byCompanyAggregation = aggregations.get("by_company"); //Get the by_company terms aggregation 281 | Bucket elasticBucket = byCompanyAggregation.getBucketByKey("Elastic"); // 282 | Avg averageAge = elasticBucket.getAggregations().get("average_age"); //Get the average_age sub-aggregation from that bucket 283 | double avg = averageAge.getValue(); 284 | ``` 285 | 286 | 请注意,如果按名称访问聚合,则需要根据您请求的聚合类型指定聚合接口,否则将抛出 ClassCastException : 287 | 288 | ``` 289 | //This will throw an exception because "by_company" is a terms aggregation but we try to retrieve it as a range aggregation 290 | Range range = aggregations.get("by_company"); 291 | ``` 292 | 293 | 也可以以聚合名称键入的映射来访问所有聚合。在这种情况下,转换为适当聚合接口需要明确发生: 294 | 295 | ``` 296 | Map aggregationMap = aggregations.getAsMap(); 297 | Terms companyAggregation = (Terms) aggregationMap.get("by_company"); 298 | ``` 299 | 300 | 还有getter 方法将所有顶级聚合作为列表返回: 301 | 302 | ``` 303 | List aggregationList = aggregations.asList(); 304 | ``` 305 | 306 | 最后但并非最不重要的是,您可以迭代所有聚合,然后根据其类型决定如何进一步处理它们: 307 | 308 | ``` 309 | for (Aggregation agg : aggregations) { 310 | String type = agg.getType(); 311 | if (type.equals(TermsAggregationBuilder.NAME)) { 312 | Bucket elasticBucket = ((Terms) agg).getBucketByKey("Elastic"); 313 | long numberOfDocs = elasticBucket.getDocCount(); 314 | } 315 | } 316 | ``` 317 | 318 | ### 检索建议 319 | 320 | 要从SearchResponse返回建议,请使用Suggest对象作为入口点,然后检索嵌套的建议对象: 321 | 322 | ``` 323 | Suggest suggest = searchResponse.getSuggest();// Use the Suggest class to access suggestions 324 | TermSuggestion termSuggestion = suggest.getSuggestion("suggest_user");// Suggestions can be retrieved by name. You need to assign them to the correct type of Suggestion class (here TermSuggestion), otherwise a ClassCastException is thrown 325 | for (TermSuggestion.Entry entry : termSuggestion.getEntries()) {// Iterate over the suggestion entries 326 | for (TermSuggestion.Entry.Option option : entry) {// Iterate over the options in one entry 327 | String suggestText = option.getText().string(); 328 | } 329 | } 330 | ``` 331 | 332 | ### 检索分析结果 333 | 334 | 从SearchResponse使用该getProfileResults()方法检索分析结果。此方法返回Map包含执行中ProfileShardResult涉及的每个分片的对象 SearchRequest。ProfileShardResult存储在Map使用唯一地标识分析结果对应的分片的密钥。 335 | 336 | 这是一个示例代码,显示如何遍历每个分片的所有分析结果: 337 | 338 | ``` 339 | Map profilingResults = searchResponse.getProfileResults(); //Retrieve the Map of ProfileShardResult from the SearchResponse 340 | for (Map.Entry profilingResult : profilingResults.entrySet()) { //Profiling results can be retrieved by shard’s key if the key is known, otherwise it might be simpler to iterate over all the profiling results 341 | String key = profilingResult.getKey();//Retrieve the key that identifies which shard the ProfileShardResult belongs to 342 | ProfileShardResult profileShardResult = profilingResult.getValue();//Retrieve the ProfileShardResult for the given shard 343 | } 344 | ``` 345 | 346 | ProfileShardResult对象本身包含一个或多个查询配置文件结果,一个针对基本的Lucene索引执行的每个查询: 347 | 348 | ``` 349 | List queryProfileShardResults = profileShardResult.getQueryProfileResults(); // 检索 QueryProfileShardResult 列表 350 | for (QueryProfileShardResult queryProfileResult : queryProfileShardResults) { 351 | //迭代每个 QueryProfileShardResult 352 | } 353 | ``` 354 | 355 | 每个都QueryProfileShardResult可以访问详细的查询树执行,作为ProfileResult对象列表返回 : 356 | 357 | ``` 358 | for (ProfileResult profileResult : queryProfileResult.getQueryResults()) {//迭代配置文件结果 359 | String queryName = profileResult.getQueryName(); //检索Lucene查询的名称 360 | long queryTimeInMillis = profileResult.getTime(); //检索在执行Lucene查询时花费的时间 361 | List profiledChildren = profileResult.getProfiledChildren();// 362 | 检索子查询的配置文件结果(如果有) 363 | } 364 | ``` 365 | 366 | Rest API文档包含有关查询分析信息描述的Profiling Queries的更多信息。 367 | 368 | 该 QueryProfileShardResult 还可以访问了Lucene的收藏家的分析信息: 369 | 370 | ``` 371 | CollectorResult collectorResult = queryProfileResult.getCollectorResult(); //检索Lucene收集器的分析结果 372 | String collectorName = collectorResult.getName(); //检索Lucene 的名字 373 | Long collectorTimeInMillis = collectorResult.getTime();//以毫秒计算的时间用于执行Lucene集合 374 | List profiledChildren = collectorResult.getProfiledChildren();// 375 | ``` 376 | 377 | 检索子集合的个人资料结果(如果有) 378 | Rest API文档包含有关Lucene收集器的分析信息的更多信息 。 379 | 380 | 以与查询树执行非常相似的方式,QueryProfileShardResult对象可以访问详细的聚合树执行: 381 | 382 | ``` 383 | AggregationProfileShardResult aggsProfileResults = profileShardResult.getAggregationProfileResults(); // 检索 AggregationProfileShardResult 384 | for (ProfileResult profileResult : aggsProfileResults.getProfileResults()) { //迭代聚合配置文件结果 385 | String aggName = profileResult.getQueryName(); //Retrieve the type of the aggregation (corresponds to Java class used to execute the aggregation) 386 | long aggTimeInMillis = profileResult.getTime();//Retrieve the time in millis spent executing the Lucene collector 387 | List profiledChildren = profileResult.getProfiledChildren(); //Retrieve the profile results for the sub-aggregations (if any) 388 | } 389 | ``` 390 | Rest API文档包含更多关关于 Profiling Aggregations 的信息 -------------------------------------------------------------------------------- /java-high-level-rest-client/supported-apis/search-scroll-api.md: -------------------------------------------------------------------------------- 1 | 2 | # Search Scroll API 3 | 4 | Scroll API可用于从搜索请求中检索大数量的结果。 5 | 6 | 为了使用滚动,需要按照给定的顺序执行以下步骤。 7 | 8 | ## 初始化搜索滚动上下文 9 | 10 | 包含一个 scroll 参数的初始化搜索请求必须通过执行 Search API 初始化滚动回话。 在处理此SearchRequest时,Elasticsearch将检测滚动参数的存在,并使搜索上下文保持相应的时间间隔。 11 | 12 | ``` 13 | SearchRequest searchRequest = new SearchRequest("posts"); 14 | SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); 15 | searchSourceBuilder.query(matchQuery("title", "Elasticsearch")); 16 | searchSourceBuilder.size(size); //Create the SearchRequest and its corresponding SearchSourceBuilder. Also optionally set the size to control how many results to retrieve at a time. 17 | searchRequest.source(searchSourceBuilder); 18 | searchRequest.scroll(TimeValue.timeValueMinutes(1L)); // Set the scroll interval 19 | SearchResponse searchResponse = client.search(searchRequest); 20 | String scrollId = searchResponse.getScrollId(); // Read the returned scroll id, which points to the search context that’s being kept alive and will be needed in the following search scroll call 21 | SearchHits hits = searchResponse.getHits(); // Retrieve the first batch of search hits 22 | ``` 23 | 24 | ## 检索所有相关文档 25 | 26 | 其次, 接收到的滚动标识符必须被设置到下一个新的滚动间隔的 SearchScrollRequest, 并通过 searchScroll 方法发送。Elasticsearch会使用新的滚动标识符返回另一批结果。 然后可以在随后的SearchScrollRequest中使用此新的滚动标识符来检索下一批结果,等等。应该循环重复此过程,直到不再返回结果,这意味着滚动已经用尽,并且已经检索到所有匹配的文档。 27 | 28 | ``` 29 | SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId); //Create the SearchScrollRequest by setting the required scroll id and the scroll interval 30 | scrollRequest.scroll(TimeValue.timeValueSeconds(30)); 31 | SearchResponse searchScrollResponse = client.searchScroll(scrollRequest); 32 | scrollId = searchScrollResponse.getScrollId(); // Read the new scroll id, which points to the search context that’s being kept alive and will be needed in the following search scroll call 33 | hits = searchScrollResponse.getHits(); //Retrieve another batch of search hits <4> 34 | assertEquals(3, hits.getTotalHits()); 35 | assertEquals(1, hits.getHits().length); 36 | assertNotNull(scrollId); 37 | ``` 38 | 39 | ## 清除滚动上下文 40 | 41 | 最后,可以使用Clear Scroll API删除最后一个滚动标识符,以释放搜索上下文。 当滚动到期时,会自动发生,但最佳实践是当滚动会话结束后尽快释放资源。 42 | 43 | ## 可选参数 44 | 45 | 构建 SearchScrollRequest 是可以选择使用以下参数: 46 | 47 | ``` 48 | scrollRequest.scroll(TimeValue.timeValueSeconds(60L)); // Scroll interval as a TimeValue 49 | scrollRequest.scroll("60s"); // Scroll interval as a String 50 | ``` 51 | 52 | ## 同步执行 53 | 54 | ``` 55 | SearchResponse searchResponse = client.searchScroll(scrollRequest); 56 | ``` 57 | 58 | ## 异步执行 59 | 60 | ``` 61 | client.searchScrollAsync(scrollRequest, new ActionListener() { 62 | @Override 63 | public void onResponse(SearchResponse searchResponse) { 64 | // 当执行成功的时候调用,响应对象以参数的形式传入 65 | } 66 | @Override 67 | public void onFailure(Exception e) { 68 | // 失败时调用,异常以参数形式传入 69 | } 70 | }); 71 | ``` 72 | 73 | ## 响应 74 | 75 | 与 Search API 一样,滚动搜索 API 也返回一个 SearchResponse 对象 76 | 77 | ### 完整示例 78 | 79 | 下面是一个滚动搜索的完整示例: 80 | ``` 81 | final Scroll scroll = new Scroll(TimeValue.timeValueMinutes(1L)); 82 | SearchRequest searchRequest = new SearchRequest("posts"); 83 | searchRequest.scroll(scroll); 84 | SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); 85 | searchSourceBuilder.query(matchQuery("title", "Elasticsearch")); 86 | searchRequest.source(searchSourceBuilder); 87 | SearchResponse searchResponse = client.search(searchRequest); // 通过发送初始化 SearchRequest 来初始化搜索上下文 88 | String scrollId = searchResponse.getScrollId(); 89 | SearchHit[] searchHits = searchResponse.getHits().getHits(); 90 | while (searchHits != null && searchHits.length > 0) { //在一个循环中通过调用 Search Scroll api 检索所有搜索命中结果,知道没有文档返回为止。 91 | //创建一个新的SearchScrollRequest,持有最近一次返回的滚动标识符和滚动间隔 92 | SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId); 93 | scrollRequest.scroll(scroll); 94 | searchResponse = client.searchScroll(scrollRequest); 95 | scrollId = searchResponse.getScrollId(); 96 | searchHits = searchResponse.getHits().getHits(); 97 | //处理返回的搜索结果 98 | } 99 | ClearScrollRequest clearScrollRequest = new ClearScrollRequest(); //一旦滚动完成,清除滚动上下文 100 | clearScrollRequest.addScrollId(scrollId); 101 | ClearScrollResponse clearScrollResponse = client.clearScroll(clearScrollRequest); 102 | boolean succeeded = clearScrollResponse.isSucceeded(); 103 | ``` 104 | -------------------------------------------------------------------------------- /java-high-level-rest-client/supported-apis/update-api.md: -------------------------------------------------------------------------------- 1 | 2 | # Update API 3 | 4 | ## 更新请求 5 | 6 | UpdateRequest 要求下列参数: 7 | 8 | ``` 9 | UpdateRequest request = new UpdateRequest( 10 | "posts", // Index 11 | "doc", // Type 12 | "1"); // Document id 13 | ``` 14 | 15 | Update API允许通过使用脚本或传递部分文档来更新现有文档。 16 | 17 | ### 使用脚本更新 18 | 19 | 该脚本可以是一个内联脚本: 20 | 21 | ``` 22 | Map parameters = singletonMap("count", 4); // 脚本参数以一个 Map 对象提供。 23 | Script inline = new Script(ScriptType.INLINE, "painless", "ctx._source.field += params.count", parameters); // 使用 painless 语言创建内联脚本,并传入参数值。 24 | request.script(inline); // 将脚本传递给更新请求对象 25 | ``` 26 | 27 | 或者是一个存储脚本: 28 | 29 | ``` 30 | // 引用一个名为 increment-field 的painless 的存储脚本 31 | Script stored = 32 | new Script(ScriptType.STORED, "painless", "increment-field", parameters); 33 | request.script(stored); // 给请求设置脚本 34 | ``` 35 | 36 | ### 使用局部文档更新 37 | 38 | 使用局部文档更新时,局部文档将与现有文档合并。 39 | 40 | 局部文档可以以不同的方式提供: 41 | 42 | ``` 43 | UpdateRequest request = new UpdateRequest("posts", "doc", "1"); 44 | String jsonString = "{" + 45 | "\"updated\":\"2017-01-01\"," + 46 | "\"reason\":\"daily update\"" + 47 | "}"; 48 | request.doc(jsonString, XContentType.JSON); // 以一个 JSON 格式的字符串提供的局部文档源 49 | ``` 50 | 51 | ``` 52 | Map jsonMap = new HashMap<>(); 53 | jsonMap.put("updated", new Date()); 54 | jsonMap.put("reason", "daily update"); 55 | UpdateRequest request = new UpdateRequest("posts", "doc", "1") 56 | .doc(jsonMap); // 以一个可自动转换为 JSON 格式的 Map 提供局部文档源 57 | ``` 58 | 59 | ``` 60 | XContentBuilder builder = XContentFactory.jsonBuilder(); 61 | builder.startObject(); 62 | { 63 | builder.field("updated", new Date()); 64 | builder.field("reason", "daily update"); 65 | } 66 | builder.endObject(); 67 | UpdateRequest request = new UpdateRequest("posts", "doc", "1") 68 | .doc(builder); // 以 XContentBuilder 对象提供局部文档源, Elasticsearch 构建辅助器将生成 JSON 格式。 69 | ``` 70 | ``` 71 | UpdateRequest request = new UpdateRequest("posts", "doc", "1") 72 | .doc("updated", new Date(), 73 | "reason", "daily update"); // 以 Object 键值对提供局部文档源,它将被转换为 JSON 格式。 74 | ``` 75 | 76 | ### 更新或插入 77 | 78 | 如果文档不存在,可以使用upsert方法定义一些将作为新文档插入的内容: 79 | 80 | ``` 81 | String jsonString = "{\"created\":\"2017-01-01\"}"; 82 | request.upsert(jsonString, XContentType.JSON); // 以字符串提供更新插入的文档源 83 | 与局部文档更新类似,可以使用接受 String, Map , XContentBuilder 或 Object 键值对的方式使用upsert 方法更新或插入文档的内容。 84 | ``` 85 | 86 | ### 可选参数 87 | 88 | 提供下列可选参数: 89 | 90 | ``` 91 | request.routing("routing"); // 路由值 92 | request.parent("parent"); //Parent 值 93 | request.timeout(TimeValue.timeValueMinutes(2)); // TimeValue 类型的等待主分片可用的超时时间 94 | request.timeout("2m"); // 字符串类型的等待主分片可用的超时时间 95 | request.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL); // Refresh policy as a WriteRequest.RefreshPolicy instance 96 | request.setRefreshPolicy("wait_for"); // Refresh policy as a String 97 | request.retryOnConflict(3); // How many times to retry the update operation if the document to update has been changed by another operation between the get and indexing phases of the update operation 98 | request.fetchSource(true); //Enable source retrieval, disabled by default 99 | request.version(2); // 版本号 100 | request.detectNoop(false); // Disable the noop detection 101 | request.scriptedUpsert(true); // Indicate that the script must run regardless of whether the document exists or not, ie the script takes care of creating the document if it does not already exist. 102 | request.docAsUpsert(true); // Indicate that the partial document must be used as the upsert document if it does not exist yet. 103 | request.waitForActiveShards(2); //Sets the number of shard copies that must be active before proceeding with the update operation. 104 | request.waitForActiveShards(ActiveShardCount.ALL); //Number of shard copies provided as a ActiveShardCount: can be ActiveShardCount.ALL, ActiveShardCount.ONE or ActiveShardCount.DEFAULT (default) 105 | ``` 106 | 107 | ``` 108 | String[] includes = new String[]{"updated", "r*"}; 109 | String[] excludes = Strings.EMPTY_ARRAY; 110 | request.fetchSource(new FetchSourceContext(true, includes, excludes)); // Configure source inclusion for specific fields 111 | ``` 112 | 113 | ``` 114 | String[] includes = Strings.EMPTY_ARRAY; 115 | String[] excludes = new String[]{"updated"}; 116 | request.fetchSource(new FetchSourceContext(true, includes, excludes)); //Configure source exclusion for specific fields 117 | ``` 118 | 119 | ### 同步执行 120 | 121 | ``` 122 | UpdateResponse updateResponse = client.update(request); 123 | ``` 124 | 125 | ### 异步执行 126 | 127 | ``` 128 | client.updateAsync(request, new ActionListener() { 129 | @Override 130 | public void onResponse(UpdateResponse updateResponse) { 131 | // Called when the execution is successfully completed. The response is provided as an argument. 132 | } 133 | @Override 134 | public void onFailure(Exception e) { 135 | // Called in case of failure. The raised exception is provided as an argument. 136 | } 137 | }); 138 | ``` 139 | 140 | ## 更新响应 141 | 142 | 返回的UpdateResponse允许获取执行操作的相关信息,如下所示: 143 | 144 | ``` 145 | String index = updateResponse.getIndex(); 146 | String type = updateResponse.getType(); 147 | String id = updateResponse.getId(); 148 | long version = updateResponse.getVersion(); 149 | if (updateResponse.getResult() == DocWriteResponse.Result.CREATED) { 150 | //Handle the case where the document was created for the first time (upsert) 151 | } else if (updateResponse.getResult() == DocWriteResponse.Result.UPDATED) { 152 | // Handle the case where the document was updated 153 | } else if (updateResponse.getResult() == DocWriteResponse.Result.DELETED) { 154 | //Handle the case where the document was deleted 155 | } else if (updateResponse.getResult() == DocWriteResponse.Result.NOOP) { 156 | //Handle the case where the document was not impacted by the update, ie no operation (noop) was executed on the document 157 | } 158 | ``` 159 | 当通过 fetchSource 方法在UpdateRequest 里设置了启用接收源,相应对象将包含被更新的文档源: 160 | 161 | ``` 162 | GetResult result = updateResponse.getGetResult(); //Retrieve the updated document as a GetResult 163 | if (result.isExists()) { 164 | String sourceAsString = result.sourceAsString(); //Retrieve the source of the updated document as a String 165 | Map sourceAsMap = result.sourceAsMap(); //Retrieve the source of the updated document as a Map 166 | byte[] sourceAsBytes = result.source(); //Retrieve the source of the updated document as a byte[] 167 | } else { 168 | //Handle the scenario where the source of the document is not present in the response (this is the case by default) 169 | } 170 | ``` 171 | 这也可以用了检查分片故障: 172 | 173 | ``` 174 | ReplicationResponse.ShardInfo shardInfo = updateResponse.getShardInfo(); 175 | if (shardInfo.getTotal() != shardInfo.getSuccessful()) { 176 | //Handle the situation where number of successful shards is less than total shards 177 | } 178 | if (shardInfo.getFailed() > 0) { 179 | for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) { 180 | String reason = failure.reason(); //Handle the potential failures 181 | } 182 | } 183 | ``` 184 | 当对一个不存在的文档执行 UpdateRequest 时,响应将包含 404 状态码,并抛出一个需要如下所示处理的 ElasticsearchException 异常: 185 | 186 | ``` 187 | UpdateRequest request = new UpdateRequest("posts", "type", "does_not_exist").doc("field", "value"); 188 | try { 189 | UpdateResponse updateResponse = client.update(request); 190 | } catch (ElasticsearchException e) { 191 | if (e.status() == RestStatus.NOT_FOUND) { 192 | // 处理由于文档不存在导致的异常。 193 | } 194 | } 195 | ``` 196 | 如果有文档版本冲突,也会抛出 ElasticsearchException: 197 | 198 | ``` 199 | UpdateRequest request = new UpdateRequest("posts", "doc", "1") 200 | .doc("field", "value") 201 | .version(1); 202 | try { 203 | UpdateResponse updateResponse = client.update(request); 204 | } catch(ElasticsearchException e) { 205 | if (e.status() == RestStatus.CONFLICT) { 206 | // 表明异常是由于返回来了版本冲突错误导致的 207 | } 208 | } 209 | ``` -------------------------------------------------------------------------------- /java-high-level-rest-client/using-java-builders.md: -------------------------------------------------------------------------------- 1 | 使用 Java 建造者 2 | 3 | Java高级REST客户端依赖于 Elasticsearch 核心项目提供的不同类型的 Java Builders 对象,包括: 4 | 5 | Query Builders 6 | The query builders are used to create the query to execute within a search request. There is a query builder for every type of query supported by the Query DSL. Each query builder implements the QueryBuilder interface and allows to set the specific options for a given type of query. Once created, the QueryBuilder object can be set as the query parameter of SearchSourceBuilder. The Search Request page shows an example of how to build a full search request using SearchSourceBuilder and QueryBuilder objects. The Building Search Queries page gives a list of all available search queries with their corresponding QueryBuilder objects and QueryBuilders helper methods. 7 | 8 | Aggregation Builders 9 | Similarly to query builders, the aggregation builders are used to create the aggregations to compute during a search request execution. There is an aggregation builder for every type of aggregation (or pipeline aggregation) supported by Elasticsearch. All builders extend the AggregationBuilder class (or PipelineAggregationBuilderclass). Once created, AggregationBuilder objects can be set as the aggregation parameter of SearchSourceBuilder. There is a example of how AggregationBuilder objects are used with SearchSourceBuilder objects to define the aggregations to compute with a search query in Search Request page. The Building Aggregations page gives a list of all available aggregations with their corresponding AggregationBuilder objects and AggregationBuilders helper methods. 10 | -------------------------------------------------------------------------------- /java-high-level-rest-client/using-java-builders/building-aggregations.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 构建聚合 4 | 5 | https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-aggregation-builders.html 6 | -------------------------------------------------------------------------------- /java-high-level-rest-client/using-java-builders/building-queries.md: -------------------------------------------------------------------------------- 1 | 2 | # 构建查询 3 | 4 | 此页面列出了在 QueryBuilders 实用程序类中所有可用的搜索查询及其对应的QueryBuilder类名和帮助方法名称。 5 | https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-query-builders.html 6 | 7 | -------------------------------------------------------------------------------- /java-low-level-rest-client.md: -------------------------------------------------------------------------------- 1 | # Java 低级 REST 客户端 2 | 3 | ## 低级客户端的功能: 4 | 5 | - 最小依赖 6 | - 负载均衡 7 | - 故障转移 8 | - 故障连接策略 (是否重新连接故障节点取决于连续失败多少次;失败次数越多,在再次尝试同一个节点之前,客户端等待的时间越长) 9 | - 持久化连接 10 | - 跟踪记录请求和响应 11 | - 自动[发现集群节点](https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/sniffer.html) -------------------------------------------------------------------------------- /java-low-level-rest-client/common-configuration.md: -------------------------------------------------------------------------------- 1 | # 通用配置 2 | 3 | 正如[初始化](https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-low-usage-initialization.html)中所解释的那样,`RestClientBuilder`支持同时提供`RequestConfigCallback`和`HttpClientConfigCallback`,它们允许任何定制的`Apache Async Http Client `。 这些回调可以修改客户端的某些特定行为,而不会覆盖`RestClient`初始化的其他任何默认配置。 本节介绍了一些需要对低级Java REST客户端进行额外配置的常见方案。 -------------------------------------------------------------------------------- /java-low-level-rest-client/common-configuration/basic-authentication.md: -------------------------------------------------------------------------------- 1 | # 基本认证 2 | 3 | 构建`RestClient`时配置`HttpClientConfigCallback`来配置基本认证。 该接口有一个方法接收`org.apache.http.impl.nio.client.HttpAsyncClientBuilder`的一个实例作为参数,并具有相同的返回类型。 `httpClientBuilder` 被修改,然后返回。 在以下示例中,设置了基本身份验证。 4 | 5 | ``` 6 | final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); 7 | credentialsProvider.setCredentials(AuthScope.ANY, 8 | new UsernamePasswordCredentials("user", "password")); 9 | 10 | RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200)) 11 | .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() { 12 | @Override 13 | public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) { 14 | return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider); 15 | } 16 | }); 17 | ``` 18 | 19 | Preemptive 身份验证可以禁用,这意味着每个发送出去的请求没有授权头,当收到`HTTP 401`响应时,将重新发送与基本身份验证头完全相同的请求。 可以通过`HttpAsyncClientBuilder`来禁用: 20 | 21 | 22 | ``` 23 | final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); 24 | credentialsProvider.setCredentials(AuthScope.ANY, 25 | new UsernamePasswordCredentials("user", "password")); 26 | 27 | RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200)) 28 | .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() { 29 | @Override 30 | public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) { 31 | httpClientBuilder.disableAuthCaching(); //禁用 preemptive 身份验证 32 | return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider); 33 | } 34 | }); 35 | ``` -------------------------------------------------------------------------------- /java-low-level-rest-client/common-configuration/encrypted-communication.md: -------------------------------------------------------------------------------- 1 | # 加密传输 2 | 3 | 可以通过`HttpClientConfigCallback`配置加密传输。 参数`org.apache.http.impl.nio.client.HttpAsyncClientBuilder` 公开了多个方法来配置加密传输:`setSSLContext`,`setSSLSessionStrategy`和`setConnectionManager`,以下是一个例子: 4 | 5 | 6 | ``` 7 | 8 | KeyStore truststore = KeyStore.getInstance("jks"); 9 | try (InputStream is = Files.newInputStream(keyStorePath)) { 10 | truststore.load(is, keyStorePass.toCharArray()); 11 | } 12 | SSLContextBuilder sslBuilder = SSLContexts.custom().loadTrustMaterial(truststore, null); 13 | final SSLContext sslContext = sslBuilder.build(); 14 | RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200, "https")) 15 | .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() { 16 | @Override 17 | public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) { 18 | return httpClientBuilder.setSSLContext(sslContext); 19 | } 20 | }); 21 | ``` 22 | 23 | 如果没有提供明确的配置,则使用[系统默认配置](http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html#CustomizingStores)。 24 | 25 | 26 | -------------------------------------------------------------------------------- /java-low-level-rest-client/common-configuration/number-of-threads.md: -------------------------------------------------------------------------------- 1 | # 线程数 2 | 3 | `Apache Http Async Client` 默认启动一个调度线程,连接管理器使用多个`worker`线程,线程的数量和CPU核数量相同(等于 `Runtime.getRuntime().availableProcessors() Runtime.getRuntime().availableProcessors()`返回的数量),线程数可以修改如下: 4 | 5 | ``` 6 | RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200)) 7 | .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() { 8 | @Override 9 | public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) { 10 | return httpClientBuilder.setDefaultIOReactorConfig( 11 | IOReactorConfig.custom().setIoThreadCount(1).build()); 12 | } 13 | }); 14 | ``` -------------------------------------------------------------------------------- /java-low-level-rest-client/common-configuration/others.md: -------------------------------------------------------------------------------- 1 | # 其他 2 | 3 | 对于其他配置,查阅 `Apache HttpAsyncClient`文档:https://hc.apache.org/httpcomponents-asyncclient-4.1.x/。 4 | -------------------------------------------------------------------------------- /java-low-level-rest-client/common-configuration/timeouts.md: -------------------------------------------------------------------------------- 1 | # 超时 2 | 3 | 配置请求超时可以通过构建器构建`RestClient`时提供`RequestConfigCallback`实例来完成。 该接口有一个方法接收`org.apache.http.client.config.RequestConfig.Builder`的一个实例作为参数,并具有相同的返回类型。 请求配置生成器可以修改,然后返回。 在下面的例子中,我们增加了连接超时(默认为1秒)和socket超时(默认为30秒)。 也调整最大重试超时时间(默认为30秒)。 4 | 5 | ``` 6 | RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200)) 7 | .setRequestConfigCallback(new RestClientBuilder.RequestConfigCallback() { 8 | @Override 9 | public RequestConfig.Builder customizeRequestConfig(RequestConfig.Builder requestConfigBuilder) { 10 | return requestConfigBuilder.setConnectTimeout(5000) 11 | .setSocketTimeout(60000); 12 | } 13 | }) 14 | .setMaxRetryTimeoutMillis(60000); 15 | ``` -------------------------------------------------------------------------------- /java-low-level-rest-client/getting-started.md: -------------------------------------------------------------------------------- 1 | # 起步 2 | 3 | 本节介绍了如何在应用程序中使用低级REST客户端。 -------------------------------------------------------------------------------- /java-low-level-rest-client/getting-started/dependencies.md: -------------------------------------------------------------------------------- 1 | # 依赖 2 | 3 | 低级 `Java REST` 客户端内部使用 [`Apache Http Async Client`](http://hc.apache.org/httpcomponents-asyncclient-dev/) 发送 `http` 请求。它依赖以下工具,即`Apache Http Async Client`依赖: 4 | 5 | - org.apache.httpcomponents:httpasyncclient 6 | - org.apache.httpcomponents:httpcore-nio 7 | - org.apache.httpcomponents:httpclient 8 | - org.apache.httpcomponents:httpcore 9 | - commons-codec:commons-codec 10 | - commons-logging:commons-logging -------------------------------------------------------------------------------- /java-low-level-rest-client/getting-started/initialization.md: -------------------------------------------------------------------------------- 1 | # 初始化 2 | 3 | 4 | `RestClient` 实例可以通过相应的 `RestClientBuilder` 类来构建,通过静态方法 `RestClient#builder(HttpHost...)` 创建。唯一必需的参数是服务的host和端口(默认9200,切记不要使用9300),以 [`HttpHost`](https://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/HttpHost.html) 实例的方式提供给建造者,如下所示: 5 | 6 | ``` 7 | RestClient restClient = RestClient.builder( 8 | new HttpHost("localhost", 9200, "http"), 9 | new HttpHost("localhost", 9201, "http")).build(); 10 | ``` 11 | 12 | `RestClient` 类是线程安全的,理想状态下它与使用它的应用程序具有相同的生命周期。当不再使用时强烈建议关闭它: 13 | 14 | ``` 15 | restClient.close(); 16 | ``` 17 | 18 | `RestClientBuilder` 在构建 `RestClient` 实例时可以设置以下的可选配置参数: 19 | 20 | ``` 21 | RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200, "http")); 22 | Header[] defaultHeaders = new Header[]{ 23 | new BasicHeader("header", "value") 24 | }; 25 | builder.setDefaultHeaders(defaultHeaders); // 设置默认头文件,避免每个请求都必须指定。 26 | ``` 27 | 28 | ``` 29 | RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200, "http")); 30 | 31 | builder.setMaxRetryTimeoutMillis(10000);//设置在同一请求进行多次尝试时应该遵守的超时时间。默认值为30秒,与默认`socket`超时相同。 如果自定义设置了`socket`超时,则应该相应地调整最大重试超时。 32 | 33 | ``` 34 | 35 | 36 | ``` 37 | RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200, "http")); 38 | builder.setFailureListener(new RestClient.FailureListener() { 39 | @Override 40 | public void onFailure(HttpHost host) { 41 | //设置每次节点发生故障时收到通知的侦听器。内部嗅探到故障时被启用。 42 | } 43 | }); 44 | ``` 45 | 46 | ``` 47 | RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200, "http")); 48 | builder.setRequestConfigCallback(new RestClientBuilder.RequestConfigCallback() { 49 | @Override 50 | public RequestConfig.Builder customizeRequestConfig(RequestConfig.Builder requestConfigBuilder) { 51 | return requestConfigBuilder.setSocketTimeout(10000); // 设置修改默认请求配置的回调(例如:请求超时,认证,或者其他 [org.apache.http.client.config.RequestConfig.Builder](https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/config/RequestConfig.Builder.html) 设置)。 52 | } 53 | }); 54 | 55 | ``` 56 | 57 | 58 | 59 | ``` 60 | RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200, "http")); 61 | builder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() { 62 | @Override 63 | public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) { 64 | return httpClientBuilder.setProxy(new HttpHost("proxy", 9000, "http")); //设置修改 http 客户端配置的回调(例如:ssl 加密通讯,或其他任何 [org.apache.http.impl.nio.client.HttpAsyncClientBuilder](http://hc.apache.org/httpcomponents-asyncclient-dev/httpasyncclient/apidocs/org/apache/http/impl/nio/client/HttpAsyncClientBuilder.html) 设置) 65 | } 66 | }); 67 | 68 | ``` 69 | -------------------------------------------------------------------------------- /java-low-level-rest-client/getting-started/javadoc.md: -------------------------------------------------------------------------------- 1 | # Javadoc 2 | 3 | 4 | https://artifacts.elastic.co/javadoc/org/elasticsearch/client/elasticsearch-rest-client/5.6.0/index.html -------------------------------------------------------------------------------- /java-low-level-rest-client/getting-started/logging.md: -------------------------------------------------------------------------------- 1 | # 日志记录 2 | 3 | Java REST 客户端使用和`Apache Async Http`客户端使用的相同日志记录库:`Apache Commons Logging`,它支持许多流行的日志记录实现。 用于启用日志记录的java包是客户端本身的`org.elasticsearch.client`,嗅探器是`org.elasticsearch.client.sniffer`。 4 | 5 | 请求 `tracer` 日志记录可以开启以curl格式记录。 这在调试时非常方便,例如在需要手动执行请求的情况下,检查是否仍然产生相同的响应。 请注意,这种类型的日志记录非常消耗资源,不应一直在生产环境中启用,而只是在需要时暂时使用。 6 | 7 | -------------------------------------------------------------------------------- /java-low-level-rest-client/getting-started/maven-repository.md: -------------------------------------------------------------------------------- 1 | # Maven Repository 2 | 3 | 托管在 4 | [ Maven Central](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.elasticsearch.client%22) 5 | 6 | Java 版本最低要求 1.7 7 | 8 | > `low-level` REST 客户端与 `elasticsearch` 的发布周期相同。可以使用版本替换,但必须是 5.0.0-alpha4 之后的版本。客户端版本与 `Elasticsearch` 服务版本之间没有关联。`low-level` REST 客户端兼容所有 Elasticsearch 版本。 9 | 10 | 11 | ## Maven 配置 12 | 13 | 使用 Maven 作依赖管理,将下列内容添加到你的 pom.xml 文件里: 14 | 15 | ``` 16 | 17 | org.elasticsearch.client 18 | elasticsearch-rest-client 19 | 5.6.4 20 | 21 | ``` 22 | 23 | ## Gradle 配置 24 | 25 | 使用 gradle 作依赖管理,将下列内容添加到你的 build.gradle 文件里: 26 | 27 | ``` 28 | dependencies { 29 | compile 'org.elasticsearch.client:elasticsearch-rest-client:5.6.4' 30 | } 31 | ``` -------------------------------------------------------------------------------- /java-low-level-rest-client/getting-started/performing-requests.md: -------------------------------------------------------------------------------- 1 | # 发送请求 2 | 3 | 4 | 一旦创建了 `RestClient`,就可以通过调用其中一个`performRequest`或`performRequestAsync`方法来发送请求。 `performRequest` 方法是同步的,并直接返回`Response`,这意味着客户端将阻塞并等待返回的响应。 `performRequestAsync` 返回 `void`,并接受一个额外的`ResponseListener`作为参数,这意味着它们是异步执行的。 提供的监听器将在请求完成或失败时通知。 5 | 6 | ``` 7 | Response response = restClient.performRequest("GET", "/"); //最简单的发送一个请求 8 | ``` 9 | 10 | 11 | ``` 12 | Map params = Collections.singletonMap("pretty", "true"); 13 | Response response = restClient.performRequest("GET", "/", params); //发送一个带参数的请求 14 | ``` 15 | 16 | ``` 17 | Map params = Collections.emptyMap(); 18 | String jsonString = "{" + 19 | "\"user\":\"kimchy\"," + 20 | "\"postDate\":\"2013-01-30\"," + 21 | "\"message\":\"trying out Elasticsearch\"" + 22 | "}"; 23 | HttpEntity entity = new NStringEntity(jsonString, ContentType.APPLICATION_JSON);// org.apache.http.HttpEntity 为了让Elasticsearch 能够解析,需要设置ContentType。 24 | Response response = restClient.performRequest("PUT", "/posts/doc/1", params, entity); 25 | 26 | ``` 27 | 28 | 29 | 30 | ``` 31 | Map params = Collections.emptyMap(); 32 | HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory consumerFactory = 33 | new HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory(30 * 1024 * 1024); //[ org.apache.http.nio.protocol.HttpAsyncResponseConsumer](http://hc.apache.org/httpcomponents-core-ga/httpcore-nio/apidocs/org/apache/http/nio/protocol/HttpAsyncResponseConsumer.html) , 34 | Response response = restClient.performRequest("GET", "/posts/_search", params, null, consumerFactory); 35 | 36 | ``` 37 | 38 | 39 | ``` 40 | ResponseListener responseListener = new ResponseListener() { 41 | @Override 42 | public void onSuccess(Response response) { 43 | // 请求成功回调 44 | } 45 | 46 | @Override 47 | public void onFailure(Exception exception) { 48 | //请求失败时回调 49 | } 50 | }; 51 | restClient.performRequestAsync("GET", "/", responseListener); //发送异步请求 52 | 53 | ``` 54 | 55 | 56 | ``` 57 | Map params = Collections.singletonMap("pretty", "true"); 58 | restClient.performRequestAsync("GET", "/", params, responseListener); // 发送带参数的异步请求 59 | 60 | ``` 61 | 62 | ``` 63 | String jsonString = "{" + 64 | "\"user\":\"kimchy\"," + 65 | "\"postDate\":\"2013-01-30\"," + 66 | "\"message\":\"trying out Elasticsearch\"" + 67 | "}"; 68 | HttpEntity entity = new NStringEntity(jsonString, ContentType.APPLICATION_JSON); 69 | restClient.performRequestAsync("PUT", "/posts/doc/1", params, entity, responseListener); 70 | 71 | ``` 72 | 73 | ``` 74 | HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory consumerFactory = 75 | new HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory(30 * 1024 * 1024); 76 | restClient.performRequestAsync("GET", "/posts/_search", params, null, consumerFactory, responseListener); 77 | 78 | ``` 79 | 80 | 以下是如何发送异步请求的基本示例: 81 | 82 | ``` 83 | final CountDownLatch latch = new CountDownLatch(documents.length); 84 | for (int i = 0; i < documents.length; i++) { 85 | restClient.performRequestAsync( 86 | "PUT", 87 | "/posts/doc/" + i, 88 | Collections.emptyMap(), 89 | //let's assume that the documents are stored in an HttpEntity array 90 | documents[i], 91 | new ResponseListener() { 92 | @Override 93 | public void onSuccess(Response response) { 94 | 95 | latch.countDown();//处理返回响应 96 | } 97 | 98 | @Override 99 | public void onFailure(Exception exception) { 100 | 101 | latch.countDown();//处理失败响应,exception 里带错误码 102 | } 103 | } 104 | ); 105 | } 106 | latch.await(); 107 | ``` 108 | 109 | 上面列出的每一种方法都支持通过`Header varargs`参数和请求一起`headers`,如下例所示: 110 | 111 | ``` 112 | Response response = restClient.performRequest("GET", "/", new BasicHeader("header", "value")); 113 | 114 | ``` 115 | ``` 116 | Header[] headers = { 117 | new BasicHeader("header1", "value1"), 118 | new BasicHeader("header2", "value2") 119 | }; 120 | restClient.performRequestAsync("GET", "/", responseListener, headers); 121 | ``` -------------------------------------------------------------------------------- /java-low-level-rest-client/getting-started/reading-responses.md: -------------------------------------------------------------------------------- 1 | # 读取响应 2 | 3 | 返回`Response`对象(`performRequest`,方法返回,`ResponseListener#onSuccess(Response)`接收) 4 | 5 | ``` 6 | Response response = restClient.performRequest("GET", "/"); 7 | RequestLine requestLine = response.getRequestLine(); //请求信息 8 | HttpHost host = response.getHost(); //返回response host信息 9 | int statusCode = response.getStatusLine().getStatusCode(); //返回状态行,获取状态码 10 | Header[] headers = response.getHeaders(); //response headers ,也可以通过名字获取 `getHeader(String)` 11 | String responseBody = EntityUtils.toString(response.getEntity()); //response org.apache.http.HttpEntity 对象 12 | 13 | ``` 14 | 15 | 请求时可能抛出一下异常(或者 `ResponseListener#onFailure(Exception)` 参数接收错误信息) 16 | 17 | - `IOException` 18 | 19 | 通信问题(例如:`SocketTimeoutException`) 20 | 21 | - `ResponseException` 22 | 23 | 返回了一个 response,但是它的状态码显示了一个错误(不是2xx)。`ResponseException` 说明连接是通的。 24 | 25 | > 对于返回404状态码的请求,不会抛出 `ResponseException`,因为这是一个预期的响应,只是表示找不到该资源。 除非`ignore`参数包含404,否则所有其他HTTP方法(例如GET)都会为404响应抛出 `ResponseException`。`ignore`是一个特殊的客户端参数,不会发送到`Elasticsearch`,并且包含以逗号分隔的错误状态码列表。 它允许控制某些错误状态代码是否应该被视为预期的响应,而不是一个例外。 这对`get api`来说很有用,因为它可以在缺少文档时返回404,在这种情况下,响应主体不会包含错误,而是通常的`get api`响应,而不是文档,因为它没有找到。 26 | 27 | 28 | 注意: 低级别的客户端不公开任何 helper jsonmarshalling和un-marshalling。 用户可以自由使用他们喜欢的库。 29 | 30 | 底层的Apache异步Http客户端附带不同的[`org.apache.http.HttpEntity`](https://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/HttpEntity.html)实现,可以使用不同的格式(流,字节数组,字符串等)提供请求主体。 至于读取响应主体,`HttpEntity#getContent`方法很方便,它返回来自先前缓冲的响应主体`InputStream`。 可以提供一个自定义的`org.apache.http.nio.protocol.HttpAsyncResponseConsumer`来控制如何读取和缓冲字节,作为替代。 31 | 32 | -------------------------------------------------------------------------------- /java-low-level-rest-client/getting-started/shading.md: -------------------------------------------------------------------------------- 1 | # Shading 2 | 3 | 4 | 为了避免版本冲突,可以在单个JAR文件(有时称为“uber JAR”或“fat JAR”)中将客户端中的依赖项隐藏并打包在客户端中。 `Shading JAR `可以通过`Gradle`和`Maven`的第三方插件完成。 5 | 6 | 请注意,Shading JAR也有影响。 例如,Shading Commons Logging层意味着第三方日志记录后端也需要被shaded 。 7 | 8 | ## Maven 配置 9 | 10 | 你可以这样配置 Maven Shade 插件 。将下列内容添加到你的 pom.xml 文件里: 11 | 12 | ``` 13 | 14 | 15 | 16 | org.apache.maven.plugins 17 | maven-shade-plugin 18 | 3.1.0 19 | 20 | 21 | package 22 | shade 23 | 24 | 25 | 26 | org.apache.http 27 | hidden.org.apache.http 28 | 29 | 30 | org.apache.logging 31 | hidden.org.apache.logging 32 | 33 | 34 | org.apache.commons.codec 35 | hidden.org.apache.commons.codec 36 | 37 | 38 | org.apache.commons.logging 39 | hidden.org.apache.commons.logging 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | ``` 49 | 50 | ## Gradle 配置 51 | 52 | 你可以这样配置 Gradle [ShadowJar](https://github.com/johnrengelman/shadow) 插件. 添加以下内容到你的 build.gradle 文件中: 53 | 54 | ``` 55 | shadowJar { 56 | relocate 'org.apache.http', 'hidden.org.apache.http' 57 | relocate 'org.apache.logging', 'hidden.org.apache.logging' 58 | relocate 'org.apache.commons.codec', 'hidden.org.apache.commons.codec' 59 | relocate 'org.apache.commons.logging', 'hidden.org.apache.commons.logging' 60 | } 61 | 62 | ``` -------------------------------------------------------------------------------- /java-low-level-rest-client/sniffer.md: -------------------------------------------------------------------------------- 1 | # 嗅探器 2 | 3 | 这是个小型库,可以允许从一个正在运行的 `Elasticsearch` 集群上自动发现节点并将节点列表更新到已经存在的 `RestClient` 实例上。 4 | 它默认使用 `Nodes Info api ` 检索属于集群的节点,并使用`jackson`解析获取的`json`响应。 5 | 6 | 与`Elasticsearch 2.x`及以上兼容。 -------------------------------------------------------------------------------- /java-low-level-rest-client/sniffer/javadoc.md: -------------------------------------------------------------------------------- 1 | # Javadoc 2 | 3 | REST 客户端嗅探器的 `javadoc` https://artifacts.elastic.co/javadoc/org/elasticsearch/client/elasticsearch-rest-client-sniffer/5.6.0/index.html 4 | -------------------------------------------------------------------------------- /java-low-level-rest-client/sniffer/maven-repository.md: -------------------------------------------------------------------------------- 1 | # Maven 仓库 2 | 3 | REST 客户端嗅探器与 elasticsearch 的发行周期相同。可以使用期望的嗅探器版本替换,但必须是 5.0.0-alpha4 之后的版本。嗅探器版本与其通信的 Elasticsearch 版本之间没有关联。嗅探器支持从 elasticsearch 2.x 及以上的版本上获取节点列表。 4 | 5 | ## Maven 配置 6 | 7 | 若使用 Maven 作依赖管理,你可以这样配置依赖。将下列内容添加到你的 pom.xml 文件里: 8 | 9 | ``` 10 | 11 | 12 | org.elasticsearch.client 13 | elasticsearch-rest-client-sniffer 14 | 5.6.4 15 | 16 | ``` 17 | 18 | ## Gradle 配置 19 | 20 | 若使用 gradle 作依赖管理,你可以这样配置依赖。将下列内容添加到你的 build.gradle 文件里: 21 | 22 | ``` 23 | dependencies { 24 | compile 'org.elasticsearch.client:elasticsearch-rest-client-sniffer:5.6.0' 25 | } 26 | ``` 27 | 28 | -------------------------------------------------------------------------------- /java-low-level-rest-client/sniffer/usage.md: -------------------------------------------------------------------------------- 1 | # 用法 2 | 3 | 一旦创建了`RestClient`实例,如 [`初始化`](https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-low-usage-initialization.html)中所示,可以将嗅探器与之相关联。 `Sniffer` 将使用关联的 `RestClient` 定期(默认为每5分钟)从集群中获取当前可用的节点列表,并通过调用 `RestClient#setHosts` 来更新它们。 4 | 5 | ``` 6 | RestClient restClient = RestClient.builder( 7 | new HttpHost("localhost", 9200, "http")) 8 | .build(); 9 | Sniffer sniffer = Sniffer.builder(restClient).build(); 10 | ``` 11 | 12 | 关闭 `Sniffer` 非常重要,如此嗅探器后台线程才能正取关闭并释放他持有的资源。 `Sniffer` 对象应该与 `RestClient` 具有相同的生命周期,并在客户端之前关闭: 13 | 14 | ``` 15 | sniffer.close(); 16 | restClient.close(); 17 | ``` 18 | 19 | `Sniffer` 默认每5分钟更新一次节点列表。这个周期可以如下方式通过提供一个参数(毫秒数)自定义设置: 20 | 21 | ``` 22 | RestClient restClient = RestClient.builder( 23 | new HttpHost("localhost", 9200, "http")) 24 | .build(); 25 | Sniffer sniffer = Sniffer.builder(restClient) 26 | .setSniffIntervalMillis(60000).build(); 27 | ``` 28 | 29 | 也可以在发生故障是启用嗅探,这意味着每次故障后将直接获取并更新节点列表,而不是等到下一次正常的更新周期。此种情况时, SniffOnFailureListener 需要首先被创建,并将实例在 RestClient 创建时提供给它。 同样的,在之后创建 Sniffer 时,他需要被关联到同一个 SniffOnFailureListener 实例上,这个实例将在每个故障发生后被通知到,然后调用 Sniffer 去执行额外的嗅探行为。 30 | 31 | ``` 32 | SniffOnFailureListener sniffOnFailureListener = new SniffOnFailureListener(); 33 | RestClient restClient = RestClient.builder(new HttpHost("localhost", 9200)) 34 | .setFailureListener(sniffOnFailureListener) //为 RestClient 实例设置故障监听器 35 | .build(); 36 | Sniffer sniffer = Sniffer.builder(restClient 37 | .setSniffAfterFailureDelayMillis(30000) /* 故障后嗅探,不仅意味着每次故障后会更新节点,也会添加普通计划外的嗅探行为,默认情况是故障之后1分钟后,假设节点将恢复正常,那么我们希望尽可能快的获知。如上所述,周期可以通过 `setSniffAfterFailureDelayMillis` 方法在创建 Sniffer 实例时进行自定义设置。 需要注意的是,当没有启用故障监听时,这最后一个配置参数不会生效 */ 38 | .build(); 39 | sniffOnFailureListener.setSniffer(sniffer); // 将 嗅探器关联到嗅探故障监听器上 40 | ``` 41 | 42 | `Elasticsearch Nodes Info api` 不会返回连接节点使用的协议,而只有他们的 `host:port `键值对,因此默认使用 `http`。如果需要使用 `https` ,必须手动创建和提供 `ElasticsearchHostsSniffer` 实例,如下所示: 43 | 44 | ``` 45 | RestClient restClient = RestClient.builder( 46 | new HttpHost("localhost", 9200, "http")) 47 | .build(); 48 | HostsSniffer hostsSniffer = new ElasticsearchHostsSniffer( 49 | restClient, 50 | ElasticsearchHostsSniffer.DEFAULT_SNIFF_REQUEST_TIMEOUT, 51 | ElasticsearchHostsSniffer.Scheme.HTTPS); 52 | Sniffer sniffer = Sniffer.builder(restClient) 53 | .setHostsSniffer(hostsSniffer).build(); 54 | 55 | ``` 56 | 57 | 使用同样的方式,可以自定义设置 sniffRequestTimeout参数,该参数默认值为 1 秒。这是一个调用 Nodes Info api 时作为 querystring 参数的超时参数,这样当服务端超市时,仍然会返回一个有效响应,虽然它可能仅包含属于集群的一部分节点,其他节点会在随后响应。 58 | 59 | ``` 60 | RestClient restClient = RestClient.builder( 61 | new HttpHost("localhost", 9200, "http")) 62 | .build(); 63 | HostsSniffer hostsSniffer = new ElasticsearchHostsSniffer( 64 | restClient, 65 | TimeUnit.SECONDS.toMillis(5), 66 | ElasticsearchHostsSniffer.Scheme.HTTP); 67 | Sniffer sniffer = Sniffer.builder(restClient) 68 | .setHostsSniffer(hostsSniffer).build(); 69 | ``` 70 | 71 | 同样的,一个自定义的 HostsSniffer 实现可以提供一个高级用法功能,比如可以从 Elasticsearch 之外的来源获取主机: 72 | 73 | ``` 74 | RestClient restClient = RestClient.builder( 75 | new HttpHost("localhost", 9200, "http")) 76 | .build(); 77 | HostsSniffer hostsSniffer = new HostsSniffer() { 78 | @Override 79 | public List sniffHosts() throws IOException { 80 | return null; // 从外部源获取主机 81 | } 82 | }; 83 | Sniffer sniffer = Sniffer.builder(restClient) 84 | .setHostsSniffer(hostsSniffer).build(); 85 | ``` -------------------------------------------------------------------------------- /overview.md: -------------------------------------------------------------------------------- 1 | # 概览 2 | 3 | Java REST 客户端分为两种: 4 | 5 | - [Java 低级 REST ](java-low-level-rest-client.md) 6 | 7 | Elasticsearch 官方低级客户端: 通过 `http`协议 与Elasticsearch服务进行通信。请求编码和响应解码保留给用户实现。与所有 Elasticsearch 版本兼容。 8 | 9 | - [Java 高级 REST ](java-high-level-rest-client.md) 10 | 11 | Elasticsearch 官方高级客户端: 基于低级客户端,提供特定的方法的API,并处理请求编码和响应解码。 --------------------------------------------------------------------------------