1、初始化
兼容性
Java High Level REST Client需要Java 1.8,並依賴於Elasticsearch核心項目,客戶端版本與客戶端開發的Elasticsearch版本相同,它接受與TransportClient
相同的請求參數,並返回相同的響應對象,如果需要將應用程序從TransportClient
遷移到新的REST客戶端,請參閱遷移指南。
High Level Client保證能夠與運行在相同主版本和大於或等於的次要版本上的任何Elasticsearch節點通信。當它與Elasticsearch節點通信時,它不需要在同一個次要版本中,因為它是向前兼容的,這意味着它支持與Elasticsearch的更高的版本進行通信,而不是與其開發的版本進行通信。
6.0客戶端能夠與任何6.x Elasticsearch節點通信,而6.1客戶端肯定能夠與6.1,6.2和任何更高版本的6.x版本通信,但是,如果6.1客戶端支持6.0節點不知道的某些API的新請求主體字段,則在與先前的Elasticsearch節點版本通信時可能存在不兼容問題,例如在6.1和6.0之間。
建議在將Elasticsearch集群升級到新的主要版本時升級High Level Client,因為REST API重要更改可能會導致意外結果,具體取決於請求命中的節點,並且只有較新版本的客戶端才支持新添加的API,一旦集群中的所有節點都升級到新的主版本,客戶端應該總是在最后更新。
Javadoc
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.4/java-rest-high-supported-apis.html
Maven倉庫
高級別Java REST客戶端托管在Maven Central上,所需的最低Java版本為1.8
。
High Level REST Client與Elasticsearch具有相同的發布周期,將版本替換為想要的客戶端版本。
如果你正在尋找SNAPSHOT版本,可以通過https://snapshots.elastic.co/maven/獲取Elastic Maven Snapshot倉庫。
Maven配置
以下是如何使用maven作為依賴關系管理器來配置依賴關系,將以下內容添加到pom.xml
文件中
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.4.2</version>
</dependency>
Gradle配置
以下是使用gradle作為依賴關系管理器配置依賴關系的方法,將以下內容添加到build.gradle
文件中:
dependencies {
compile 'org.elasticsearch.client:elasticsearch-rest-high-level-client:6.4.2'
}
Lucene Snapshot倉庫
任何主要版本(如測試版)的最新版本可能都是基於Lucene Snapshot版本構建的,在這種情況下,你將無法解析客戶端的Lucene依賴關系。
例如,如果要使用依賴於Lucene 7.0.0-snapshot-00142c9
的6.0.0-beta1
版本,則必須定義以下存儲庫。
對於Maven:
<repository>
<id>elastic-lucene-snapshots</id>
<name>Elastic Lucene Snapshots</name>
<url>http://s3.amazonaws.com/download.elasticsearch.org/lucenesnapshots/00142c9</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
對於Gradle:
maven {
url 'http://s3.amazonaws.com/download.elasticsearch.org/lucenesnapshots/00142c9'
}
依賴關系
High Level Java REST Client依賴於以下工件及其傳遞依賴性:
- org.elasticsearch.client:elasticsearch-rest-client
- org.elasticsearch:elasticsearch
初始化
RestHighLevelClient
實例需要按如下方式構建REST低級別客戶端構建器:
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http"),
new HttpHost("localhost", 9201, "http")));
高級別客戶端將在內部創建用於根據提供的構建器執行請求的低級別客戶端,該低級別客戶端維護一個連接池並啟動一些線程,因此當你完好無損地關閉高級別客戶端時,它將關閉內部低級別客戶端以釋放這些資源,這可以通過close
來完成:
client.close();
在關於Java High Level Client的本文檔的其余部分中,RestHighLevelClient
實例將被引用為client
。
RequestOptions
RestHighLevelClient
中的所有API都接受RequestOptions
,你可以用來不會改變Elasticsearch執行請求的的方式自定義請求。例如,你可以在此處指定NodeSelector
來控制哪個節點接收請求,有關自定義選項的更多示例,請參閱低級別客戶端文檔。
2、Index API
索引請求
IndexRequest
需要以下參數:
IndexRequest request = new IndexRequest(
"posts",
"doc",
"1");
String jsonString = "{" +
"\"user\":\"kimchy\"," +
"\"postDate\":\"2013-01-30\"," +
"\"message\":\"trying out Elasticsearch\"" +
"}";
request.source(jsonString, XContentType.JSON);
posts
— 索引。doc
— 類型。1
— 文檔ID。- 文檔源以字符串形式提供。
提供文檔源
除了上面顯示的String
示例之外,還可以以不同的方式提供文檔源:
Map<String, Object> jsonMap = new HashMap<>();
jsonMap.put("user", "kimchy");
jsonMap.put("postDate", new Date());
jsonMap.put("message", "trying out Elasticsearch");
IndexRequest indexRequest = new IndexRequest("posts", "doc", "1")
.source(jsonMap);
- 文檔源作為
Map
提供,可自動轉換為JSON格式。
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
{
builder.field("user", "kimchy");
builder.timeField("postDate", new Date());
builder.field("message", "trying out Elasticsearch");
}
builder.endObject();
IndexRequest indexRequest = new IndexRequest("posts", "doc", "1")
.source(builder);
- 文檔源作為
XContentBuilder
對象提供,Elasticsearch內置輔助生成JSON內容。
IndexRequest indexRequest = new IndexRequest("posts", "doc", "1")
.source("user", "kimchy",
"postDate", new Date(),
"message", "trying out Elasticsearch");
- 文檔源作為
Object
鍵值對提供,轉換為JSON格式。
可選參數
可以選擇提供以下參數:
request.routing("routing");
- 路由值。
request.parent("parent");
- parent值。
request.timeout(TimeValue.timeValueSeconds(1));
request.timeout("1s");
- 等待主碎片可用的作為
TimeValue
的超時。 - 等待主碎片可用的作為
String
的超時。
request.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
request.setRefreshPolicy("wait_for");
- 刷新策略作為
WriteRequest.RefreshPolicy
實例提供。 - 刷新策略作為
String
提供。
request.version(2);
- 版本。
request.versionType(VersionType.EXTERNAL);
- 版本類型。
request.opType(DocWriteRequest.OpType.CREATE);
request.opType("create");
- 操作類型作為
DocWriteRequest.OpType
值提供。 - 作為
String
提供的操作類型:可以為create
或update
(默認)。
request.setPipeline("pipeline");
- 索引文檔之前要執行的攝取管道的名稱。
同步執行
以下列方式執行IndexRequest
時,客戶端在繼續執行代碼之前等待返回IndexResponse
:
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
異步執行
執行IndexRequest
也可以以異步方式完成,以便客戶端可以直接返回,用戶需要通過將請求和偵聽器傳遞給異步索引方法來指定響應或潛在故障的處理方式:
client.indexAsync(request, RequestOptions.DEFAULT, listener);
- 要執行的
IndexRequest
和執行完成時要使用的ActionListener
。
異步方法不會阻塞並立即返回,一旦完成,如果執行成功完成,則使用onResponse
方法回調ActionListener
,如果失敗則使用onFailure
方法。
index
的典型偵聽器如下所示:
listener = new ActionListener<IndexResponse>() {
@Override
public void onResponse(IndexResponse indexResponse) {
}
@Override
public void onFailure(Exception e) {
}
};
onResponse
— 執行成功完成時調用。onFailure
— 當整個IndexRequest
失敗時調用。
索引響應
返回的IndexResponse
允許檢索有關已執行操作的信息,如下所示:
String index = indexResponse.getIndex();
String type = indexResponse.getType();
String id = indexResponse.getId();
long version = indexResponse.getVersion();
if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
} else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
}
ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure :
shardInfo.getFailures()) {
String reason = failure.reason();
}
}
- 處理(如果需要)第一次創建文檔的情況。
- 處理(如果需要)文檔被重寫的情況,因為它已經存在。
- 處理成功碎片數小於總碎片數的情況。
- 處理潛在的失敗。
如果存在版本沖突,則拋出ElasticsearchException
:
IndexRequest request = new IndexRequest("posts", "doc", "1")
.source("field", "value")
.version(1);
try {
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
} catch(ElasticsearchException e) {
if (e.status() == RestStatus.CONFLICT) {
}
}
- 引發的異常表示返回了版本沖突錯誤。
如果將opType
設置為create
並且已存在具有相同索引、類型和ID的文檔,則會發生相同的情況:
IndexRequest request = new IndexRequest("posts", "doc", "1")
.source("field", "value")
.opType(DocWriteRequest.OpType.CREATE);
try {
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
} catch(ElasticsearchException e) {
if (e.status() == RestStatus.CONFLICT) {
}
}
3、Get API
Get請求
GetRequest
需要以下參數:
GetRequest getRequest = new GetRequest(
"posts",
"doc",
"1");
posts
— 索引。doc
— 類型。1
— 文檔id。
可選參數
可以選擇提供以下參數:
request.fetchSourceContext(FetchSourceContext.DO_NOT_FETCH_SOURCE);
- 禁用源檢索,默認情況下啟用
String[] includes = new String[]{"message", "*Date"};
String[] excludes = Strings.EMPTY_ARRAY;
FetchSourceContext fetchSourceContext =
new FetchSourceContext(true, includes, excludes);
request.fetchSourceContext(fetchSourceContext);
- 為特定字段配置源包含
String[] includes = Strings.EMPTY_ARRAY;
String[] excludes = new String[]{"message"};
FetchSourceContext fetchSourceContext =
new FetchSourceContext(true, includes, excludes);
request.fetchSourceContext(fetchSourceContext);
- 為特定字段配置源排除
request.storedFields("message");
GetResponse getResponse = client.get(request, RequestOptions.DEFAULT);
String message = getResponse.getField("message").getValue();
- 配置特定存儲字段的檢索(要求字段分別存儲在映射中)。
- 檢索
message
存儲字段(要求字段分別存儲在映射中)。
request.routing("routing");
- 路由值。
request.parent("parent");
- parent值。
request.preference("preference");
- 偏好值。
request.realtime(false);
- 將
realtime
標志設置為false
(默認為true
)。
request.refresh(true);
- 在檢索文檔之前執行刷新(默認為
false
)。
request.version(2);
- 版本。
request.versionType(VersionType.EXTERNAL);
- 版本類型。
同步執行
以下列方式執行GetRequest
時,客戶端在繼續執行代碼之前等待返回GetResponse
:
GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
異步執行
執行GetRequest
也可以以異步方式完成,以便客戶端可以直接返回,用戶需要通過將請求和偵聽器傳遞給異步get
方法來指定響應或潛在故障的處理方式:
client.getAsync(request, RequestOptions.DEFAULT, listener);
- 要執行的
GetRequest
和執行完成時要使用的ActionListener
。
異步方法不會阻塞並立即返回,完成后,如果執行成功完成,則使用onResponse
方法回調ActionListener
,如果失敗則使用onFailure
方法。
get
的典型監聽器看起來像:
ActionListener<GetResponse> listener = new ActionListener<GetResponse>() {
@Override
public void onResponse(GetResponse getResponse) {
}
@Override
public void onFailure(Exception e) {
}
};
onResponse
— 執行成功完成時調用。onFailure
— 在整個GetRequest失敗時調用。
Get響應
返回的GetResponse
允許檢索所請求的文檔及其元數據和最終存儲的字段。
String index = getResponse.getIndex();
String type = getResponse.getType();
String id = getResponse.getId();
if (getResponse.isExists()) {
long version = getResponse.getVersion();
String sourceAsString = getResponse.getSourceAsString();
Map<String, Object> sourceAsMap = getResponse.getSourceAsMap();
byte[] sourceAsBytes = getResponse.getSourceAsBytes();
} else {
}
- 以字符串形式檢索文檔。
- 將文檔檢索為
Map<String, Object>
。 - 以
byte[]
的形式檢索文檔。 - 處理未找到文檔的方案,請注意,雖然返回的響應具有
404
狀態代碼,但返回有效的GetResponse
而不是拋出異常,此類響應不包含任何源文檔,並且其isExists
方法返回false
。
當針對不存在的索引執行get
請求時,響應具有404
狀態代碼,拋出ElasticsearchException
,需要按如下方式處理:
GetRequest request = new GetRequest("does_not_exist", "doc", "1");
try {
GetResponse getResponse = client.get(request, RequestOptions.DEFAULT);
} catch (ElasticsearchException e) {
if (e.status() == RestStatus.NOT_FOUND) {
}
}
- 處理拋出的異常,因為索引不存在。
如果已請求特定文檔版本,並且現有文檔具有不同的版本號,則會引發版本沖突:
try {
GetRequest request = new GetRequest("posts", "doc", "1").version(2);
GetResponse getResponse = client.get(request, RequestOptions.DEFAULT);
} catch (ElasticsearchException exception) {
if (exception.status() == RestStatus.CONFLICT) {
}
}
引發的異常表示返回了版本沖突錯誤。
4、Exists API
如果文檔存在,則exists
API返回true
,否則返回false
。
Exists請求
它就像Get API一樣使用GetRequest
,支持所有可選參數,由於exists()
只返回true
或false
,我們建議關閉獲取_source
和任何存儲的字段,以便請求稍微輕一點:
GetRequest getRequest = new GetRequest(
"posts",
"doc",
"1");
getRequest.fetchSourceContext(new FetchSourceContext(false));
getRequest.storedFields("_none_");
posts
— 索引。doc
— 類型。1
— 索引id。FetchSourceContext(false)
— 禁用提取_source
。storedFields("_none_")
— 禁用提取存儲的字段。
同步執行
以下列方式執行GetRequest
時,客戶端在繼續執行代碼之前等待返回boolean
:
boolean exists = client.exists(getRequest, RequestOptions.DEFAULT);
異步執行
執行GetRequest
也可以以異步方式完成,以便客戶端可以直接返回,用戶需要通過將請求和偵聽器傳遞給異步exists
方法來指定響應或潛在故障的處理方式:
client.existsAsync(getRequest, RequestOptions.DEFAULT, listener);
- 要執行的
GetRequest
和執行完成時要使用的ActionListener
。
異步方法不會阻塞並立即返回,完成后,如果執行成功完成,則使用onResponse
方法回調ActionListener
,如果失敗則使用onFailure
方法。
exists
的典型偵聽器如下所示:
ActionListener<Boolean> listener = new ActionListener<Boolean>() {
@Override
public void onResponse(Boolean exists) {
}
@Override
public void onFailure(Exception e) {
}
};
onResponse
— 執行成功完成時調用。onFailure
— 在整個GetRequest
失敗時調用。
5、Delete API
Delete請求
DeleteRequest
沒有參數。
DeleteRequest request = new DeleteRequest(
"posts",
"doc",
"1");
posts
— 索引。doc
— 類型。1
— 文檔id。
可選參數
可以選擇提供以下參數:
request.routing("routing");
- 路由值。
request.parent("parent");
- parent值。
request.timeout(TimeValue.timeValueMinutes(2));
request.timeout("2m");
- 等待主碎片可用的作為
TimeValue
的超時。 - 等待主碎片可用的作為
String
的超時。
request.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
request.setRefreshPolicy("wait_for");
- 將刷新策略作為
WriteRequest.RefreshPolicy
實例。 - 將刷新策略作為
String
。
request.version(2);
- 版本。
request.versionType(VersionType.EXTERNAL);
- 版本類型。
同步執行
以下列方式執行DeleteRequest
時,客戶端在繼續執行代碼之前等待返回DeleteResponse
:
DeleteResponse deleteResponse = client.delete(
request, RequestOptions.DEFAULT);
異步執行
執行DeleteRequest
也可以以異步方式完成,以便客戶端可以直接返回,用戶需要通過將請求和偵聽器傳遞給異步刪除方法來指定響應或潛在故障的處理方式:
client.deleteAsync(request, RequestOptions.DEFAULT, listener);
- 要執行的
DeleteRequest
和執行完成時要使用的ActionListener
。
異步方法不會阻塞並立即返回,完成后,如果執行成功完成,則使用onResponse
方法回調ActionListener
,如果失敗則使用onFailure
方法。
delete
的典型偵聽器如下所示:
listener = new ActionListener<DeleteResponse>() {
@Override
public void onResponse(DeleteResponse deleteResponse) {
}
@Override
public void onFailure(Exception e) {
}
};
onResponse
— 執行成功完成時調用。onFailure
— 在整個DeleteRequest
失敗時調用。
Delete響應
返回的DeleteResponse
允許檢索有關已執行操作的信息,如下所示:
String index = deleteResponse.getIndex();
String type = deleteResponse.getType();
String id = deleteResponse.getId();
long version = deleteResponse.getVersion();
ReplicationResponse.ShardInfo shardInfo = deleteResponse.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure :
shardInfo.getFailures()) {
String reason = failure.reason();
}
}
- 處理成功碎片數小於總分片數的情況。
- 處理潛在的失敗。
還可以檢查文檔是否被找到:
DeleteRequest request = new DeleteRequest("posts", "doc", "does_not_exist");
DeleteResponse deleteResponse = client.delete(
request, RequestOptions.DEFAULT);
if (deleteResponse.getResult() == DocWriteResponse.Result.NOT_FOUND) {
}
- 如果找不到要刪除的文檔,請執行某些操作。
如果存在版本沖突,則拋出ElasticsearchException
:
try {
DeleteResponse deleteResponse = client.delete(
new DeleteRequest("posts", "doc", "1").version(2),
RequestOptions.DEFAULT);
} catch (ElasticsearchException exception) {
if (exception.status() == RestStatus.CONFLICT) {
}
}
- 引發的異常表示返回了版本沖突錯誤。
說明此部分官方地址:
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.4/_search_apis.html
6、Search API
Search Request
SearchRequest用於與搜索文檔、聚合、建議相關的任何操作,還提供了請求突出顯示結果文檔的方法。
最基本的形式,我們可以添加一個查詢請求:
SearchRequest searchRequest = new SearchRequest();
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
searchRequest.source(searchSourceBuilder);
- 創建SeachRequest。如果沒有參數,則運行所有索引。
- 大多數搜索參數被添加到SearchSourceBuilder。它為進入搜索請求體的所有內容提供。
- 向SearchSourceBuilder添加一個match_all查詢。
- 將SearchSourceBuilder添加到SeachRequest中。
Optional arguments
可選參數
讓我們先看看SearchRequest的一些可選參數:
SearchRequest searchRequest = new SearchRequest("posts");
將請求限制為索引posts
有幾個其他有趣的可選參數:
searchRequest.routing("routing");
設置路由參數
searchRequest.indicesOptions(IndicesOptions.lenientExpandOpen());
設置IndicesOptions可以控制如何解析不可用的索引以及如何展開通配符表達式
searchRequest.preference("_local");
使用preference參數,例如,執行搜索以選擇本地碎片。默認設置是在碎片之間隨機分配。
SearchSourceBuilder
大多數控制搜索行為的選項都可以在SearchSourceBuilder上設置,它或多或少地包含了Rest API的搜索請求體中的選項。
以下是一些常見的選擇:
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.termQuery("user", "kimchy"));
sourceBuilder.from(0);
sourceBuilder.size(5);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
- 使用默認選項創建一個SearchSourceBuilder。
- 設置查詢。成為任何類型的QueryBuilder
- 設置from選項,該選項確定要開始搜索的結果索引。默認值為0。
- 設置確定要返回的搜索結果數量的大小選項。默認為10。
- 設置一個可選的超時,控制允許搜索的時間。
之后,SearchSourceBuilder只需要添加到SearchRequest:
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("posts");
searchRequest.source(sourceBuilder);
Building query
建立查詢
搜索查詢是使用QueryBuilder對象創建的。對於Elasticsearch的查詢DSL支持的每個搜索查詢類型,都存在一個QueryBuilder。
QueryBuilder可以使用它的構造函數創建:
MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("user", "kimchy");
創建一個全文本匹配查詢,在“user”字段上匹配文本“kimchy”
一旦創建,QueryBuilder對象提供方法來配置它創建的搜索查詢的選項:
matchQueryBuilder.fuzziness(Fuzziness.AUTO);
matchQueryBuilder.prefixLength(3);
matchQueryBuilder.maxExpansions(10);
- 對匹配查詢啟用模糊匹配
- 在匹配查詢中設置前綴長度選項
- 設置最大擴展選項來控制查詢的模糊過程
還可以使用QueryBuilders實用程序類創建QueryBuilder對象。這個類提供了可以使用連貫編程風格創建QueryBuilder對象的助手方法:
QueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("user", "kimchy")
.fuzziness(Fuzziness.AUTO)
.prefixLength(3)
.maxExpansions(10);
無論使用什么方法創建它,QueryBuilder對象都必須添加到SearchSourceBuilder中,如下所示:
searchSourceBuilder.query(matchQueryBuilder);
構建查詢頁面提供了所有可用搜索查詢的列表,其中包含相應的QueryBuilder對象和QueryBuilders助手方法。
Specifying Sorting
指定排序
SearchSourceBuilder允許添加一個或多個SortBuilder實例。有四種特殊的實現(Field-、Score-、GeoDistance-和ScriptSortBuilder)。
sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC));
sourceBuilder.sort(new FieldSortBuilder("_id").order(SortOrder.ASC));
- 按_score降序排序(默認)
- 還可以按_id字段升序排序
Source filtering
源過濾
默認情況下,搜索請求會返回文檔’ _source ‘的內容,但是就像在Rest API中一樣,您可以覆蓋這種行為。例如,你可以完全關閉’ _source '檢索:
sourceBuilder.fetchSource(false);
該方法還接受一個由一個或多個通配符模式組成的數組,以控制以更細粒度的方式包含或排除哪些字段:
String[] includeFields = new String[] {"title", "innerObject.*"};
String[] excludeFields = new String[] {"user"};
sourceBuilder.fetchSource(includeFields, excludeFields);
Requesting Highlighting
高亮查詢
可以通過在SearchSourceBuilder上設置HighlightBuilder來突出顯示搜索結果。通過添加一個或多個HighlightBuilder,可以為每個字段定義不同的突出顯示行為。字段實例到HighlightBuilder。
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
HighlightBuilder highlightBuilder = new HighlightBuilder();
HighlightBuilder.Field highlightTitle =
new HighlightBuilder.Field("title");
highlightTitle.highlighterType("unified");
highlightBuilder.field(highlightTitle);
HighlightBuilder.Field highlightUser = new HighlightBuilder.Field("user");
highlightBuilder.field(highlightUser);
searchSourceBuilder.highlighter(highlightBuilder);
- 創建一個新的HighlightBuilder
- 為標題欄創建一個高光欄
- 設置字段高亮字體
- 將字段高光添加到高光生成器
Rest API文檔中詳細解釋了許多選項。Rest API參數(例如pre_tags)通常由同名的setter(例如#preTags(String…))更改。
Requesting Aggregation
聚合查詢
通過首先創建適當的AggregationBuilder,然后在SearchSourceBuilder上設置它,可以將聚合添加到搜索中。在下面的例子中,我們創建了一個基於公司名稱的術語聚合,其中包含一個關於公司員工平均年齡的子聚合:
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
TermsAggregationBuilder aggregation = AggregationBuilders.terms("by_company")
.field("company.keyword");
aggregation.subAggregation(AggregationBuilders.avg("average_age")
.field("age"));
searchSourceBuilder.aggregation(aggregation);
Requesting Suggestion
使用建議
要向搜索請求添加建議,請使用可以從SuggestBuilders factory類輕松訪問的SuggestionBuilder實現之一。建議生成器需要添加到頂級的SuggestBuilder中,其本身可以設置在SearchSourceBuilder中。
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SuggestionBuilder termSuggestionBuilder =
SuggestBuilders.termSuggestion("user").text("kmichy");
SuggestBuilder suggestBuilder = new SuggestBuilder();
suggestBuilder.addSuggestion("suggest_user", termSuggestionBuilder);
searchSourceBuilder.suggest(suggestBuilder);
- 為用戶字段和文本kmichy創建一個新的termtionbuilder
- 添加建議生成器並將其命名為suggest_user
Profiling Queries and Aggregationsedit
分析查詢和聚合
配置文件API可用於配置特定搜索請求的查詢和聚合的執行。為了使用它,配置文件標志必須設置為真在SearchSourceBuilder:
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.profile(true);
一旦檢索請求是執行相應的回應類別將包含分析結果。
Asynchronous execution
異步執行
還可以以異步方式執行SearchRequest,以便客戶機可以直接返回。用戶需要通過向異步搜索方法傳遞請求和偵聽器來指定如何處理響應或潛在故障:
client.searchAsync(searchRequest, RequestOptions.DEFAULT, listener);
執行的SearchRequest和執行完成時使用的ActionListener
異步方法不會阻塞,而是立即返回。一旦完成,如果執行成功完成,則使用onResponse方法調用ActionListener;如果執行失敗,則使用onFailure方法調用它。失敗場景和預期的異常與同步執行情況相同。
典型的搜索監聽器是這樣的:
ActionListener<SearchResponse> listener = new ActionListener<SearchResponse>() {
@Override
public void onResponse(SearchResponse searchResponse) {
}
@Override
public void onFailure(Exception e) {
}
};
onResponse當執行成功完成時,調用。
onFailure整個檢索請求失敗時調用。
SearchResponse
SearchResponse
執行搜索返回的SearchResponse提供了關於搜索執行本身以及對返回文檔的訪問的詳細信息。首先,有關於請求執行本身的有用信息,如HTTP狀態碼、執行時間或請求是否提前終止或超時:
RestStatus status = searchResponse.status();
TimeValue took = searchResponse.getTook();
Boolean terminatedEarly = searchResponse.isTerminatedEarly();
boolean timedOut = searchResponse.isTimedOut();
其次,響應還通過提供關於受搜索影響的碎片總數以及成功碎片和不成功碎片的統計信息,提供關於碎片級別上執行的信息。可能的故障也可以通過迭代shardsearchfailure數組來處理,如下面的例子所示:
int totalShards = searchResponse.getTotalShards();
int successfulShards = searchResponse.getSuccessfulShards();
int failedShards = searchResponse.getFailedShards();
for (ShardSearchFailure failure : searchResponse.getShardFailures()) {
// failures should be handled here
}
Retrieving SearchHits
檢索SearchHits
要訪問返回的文檔,我們需要首先獲得響應中包含的SearchHits:
SearchHits hits = searchResponse.getHits();
SearchHits提供關於所有點擊的全局信息,比如總點擊數或最大得分:
TotalHits totalHits = hits.getTotalHits();
// the total number of hits, must be interpreted in the context of totalHits.relation
long numHits = totalHits.value;
// whether the number of hits is accurate (EQUAL_TO) or a lower bound of the total (GREATER_THAN_OR_EQUAL_TO)
TotalHits.Relation relation = totalHits.relation;
float maxScore = hits.getMaxScore();
嵌套在SearchHits是可以迭代的單個搜索結果:
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
// do something with the SearchHit
}
SearchHit提供了對基本信息的訪問,比如索引、文檔ID和每次搜索命中的分數:
String index = hit.getIndex();
String id = hit.getId();
float score = hit.getScore();
此外,它還允許您以簡單的JSON-String或鍵/值對映射的形式獲取文檔源。在此映射中,常規字段由字段名作為鍵值,並包含字段值。多值字段作為對象列表返回,嵌套對象作為另一個鍵/值映射返回。這些情況需要相應地進行判定:
String sourceAsString = hit.getSourceAsString();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String documentTitle = (String) sourceAsMap.get("title");
List<Object> users = (List<Object>) sourceAsMap.get("user");
Map<String, Object> innerObject =
(Map<String, Object>) sourceAsMap.get("innerObject");
Retrieving Highlighting
檢索高亮
如果需要,可以從結果中的每個SearchHit檢索突出顯示的文本片段。hit對象提供了從字段名到HighlightField實例的映射,每個實例包含一個或多個突出顯示的文本片段:
SearchHits hits = searchResponse.getHits();
for (SearchHit hit : hits.getHits()) {
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
HighlightField highlight = highlightFields.get("title");
Text[] fragments = highlight.fragments();
String fragmentString = fragments[0].string();
}
獲取標題字段的高亮顯示
獲取一個或多個包含突出顯示字段內容的片段
Retrieving Aggregations
檢索聚合
通過首先獲取聚合樹的根,即Aggregations對象,然后通過名稱獲取聚合,可以從SearchResponse檢索聚合。
Aggregations aggregations = searchResponse.getAggregations();
Terms byCompanyAggregation = aggregations.get("by_company");
Bucket elasticBucket = byCompanyAggregation.getBucketByKey("Elastic");
Avg averageAge = elasticBucket.getAggregations().get("average_age");
double avg = averageAge.getValue();
- 得到by_company聚合
- 得到Elastic對應的Bucket
- 從該bucket獲取average_age子聚合
注意,如果按名稱訪問聚合,需要根據請求的聚合類型指定聚合接口,否則會拋出ClassCastException:
Range range = aggregations.get("by_company");
會拋出一個異常,因為“by_company”是一個術語聚合,但我們試圖將其檢索為一個范圍聚合。
還可以將所有聚合作為映射訪問,映射由聚合名稱作為鍵。在這種情況下,需要顯式地轉換到適當的聚合接口:
Map<String, Aggregation> aggregationMap = aggregations.getAsMap();
Terms companyAggregation = (Terms) aggregationMap.get("by_company");
還有getter返回所有頂級的聚合為一個列表:
List<Aggregation> aggregationList = aggregations.asList();
最后但並非最不重要的是,你可以迭代所有的聚合,然后決定如何進一步處理他們基於他們的類型:
for (Aggregation agg : aggregations) {
String type = agg.getType();
if (type.equals(TermsAggregationBuilder.NAME)) {
Bucket elasticBucket = ((Terms) agg).getBucketByKey("Elastic");
long numberOfDocs = elasticBucket.getDocCount();
}
}
Retrieving Suggestion
檢索建議
要從SearchResponse獲取建議,使用Suggest對象作為入口點,然后檢索嵌套的建議對象:
Suggest suggest = searchResponse.getSuggest();
TermSuggestion termSuggestion = suggest.getSuggestion("suggest_user");
for (TermSuggestion.Entry entry : termSuggestion.getEntries()) {
for (TermSuggestion.Entry.Option option : entry) {
String suggestText = option.getText().string();
}
}
-
使用Suggest類來訪問建議
-
可以通過名稱檢索建議。您需要將它們分配給建議類的正確類型(這里是TermSuggestion),否則將拋出ClassCastException
-
迭代建議條目
-
遍歷一個條目中的選項
Retrieving Profiling Results
檢索分析結果
使用getProfileResults()方法從SearchResponse檢索分析結果。此方法為SearchRequest執行中涉及的每個碎片返回一個包含ProfileShardResult對象的映射。ProfileShardResult使用唯一標識配置文件結果所對應的碎片的鍵存儲在映射中。
下面的示例代碼演示了如何遍歷每個碎片的所有分析結果:
Map<String, ProfileShardResult> profilingResults =
searchResponse.getProfileResults();
for (Map.Entry<String, ProfileShardResult> profilingResult : profilingResults.entrySet()) {
String key = profilingResult.getKey();
ProfileShardResult profileShardResult = profilingResult.getValue();
}
- 從SearchResponse檢索ProfileShardResult的地圖
- 如果鍵是已知的,那么可以通過shard的鍵檢索分析結果,否則遍歷所有分析結果可能更簡單
- 檢索標識ProfileShardResult屬於哪個碎片的鍵
- 檢索給定碎片的ProfileShardResult
ProfileShardResult對象本身包含一個或多個查詢配置文件結果,每個查詢一個針對底層Lucene索引執行:
List<QueryProfileShardResult> queryProfileShardResults =
profileShardResult.getQueryProfileResults();
for (QueryProfileShardResult queryProfileResult : queryProfileShardResults) {
}
- 檢索QueryProfileShardResult的列表
- 遍歷每個QueryProfileShardResult
每個QueryProfileShardResult都允許訪問詳細的查詢樹執行,以ProfileResult對象列表的形式返回:
for (ProfileResult profileResult : queryProfileResult.getQueryResults()) {
String queryName = profileResult.getQueryName();
long queryTimeInMillis = profileResult.getTime();
List<ProfileResult> profiledChildren = profileResult.getProfiledChildren();
}
- 遍歷配置文件結果
- 檢索Lucene查詢的名稱
- 檢索在millis中執行Lucene查詢所花費的時間
- 檢索子查詢的概要結果(如果有的話)
Rest API文檔包含關於分析查詢的更多信息,其中描述了查詢分析信息。
QueryProfileShardResult還為Lucene收集器提供了對概要信息的訪問:
CollectorResult collectorResult = queryProfileResult.getCollectorResult();
String collectorName = collectorResult.getName();
Long collectorTimeInMillis = collectorResult.getTime();
List<CollectorResult> profiledChildren = collectorResult.getProfiledChildren();
- 檢索Lucene收集器的分析結果
- 檢索Lucene收集器的名稱
- 檢索在millis中執行Lucene收集器所花費的時間
- 檢索子收集器的配置文件結果(如果有)
Rest API文檔包含關於Lucene收集器的分析信息的更多信息。看到分析查詢。
QueryProfileShardResult對象以與查詢樹執行非常相似的方式訪問詳細的聚合樹執行:
AggregationProfileShardResult aggsProfileResults =
profileShardResult.getAggregationProfileResults();
for (ProfileResult profileResult : aggsProfileResults.getProfileResults()) {
String aggName = profileResult.getQueryName();
long aggTimeInMillis = profileResult.getTime();
List<ProfileResult> profiledChildren = profileResult.getProfiledChildren();
}
- 檢索AggregationProfileShardResult
- 遍歷聚合配置文件結果
- 檢索聚合的類型(對應於用於執行聚合的Java類)
- 檢索在millis中執行Lucene收集器所花費的時間
- 檢索子聚合的配置文件結果(如果有的話)
注:其它操作請查看https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.4/java-rest-high-supported-apis.html大同小異。
-
這里官方說的對於TransportClient,7.0不建議使用,8.0刪除
-
IndexRequest構建情況是相同的,區別在於構建IndexResponse,transport使用RequestBuilder的相關prepare遺留方法去構建Response,rest直接使用client的對應方法去返回一個對應的Response。
比如transportClient.prepareBulk().get()直接變成client.bulk()得到的同樣都是BulkResponse;
prepareSearch變成了search方法 -
不用Builder怎么執行——直接client執行
更多請查看博客:https://www.unclewang.info/learn/es/714/,https://segmentfault.com/a/1190000015138673