Java High Level REST Client 中文API(僅供參考)

一、初始化

兼容性

Java High Level REST Client須要Java 1.8,並依賴於Elasticsearch核心項目,客戶端版本與客戶端開發的Elasticsearch版本相同,它接受與TransportClient相同的請求參數,並返回相同的響應對象,若是須要將應用程序從TransportClient遷移到新的REST客戶端,請參閱遷移指南。html

High Level Client保證可以與運行在相同主版本和大於或等於的次要版本上的任何Elasticsearch節點通訊。當它與Elasticsearch節點通訊時,它不須要在同一個次要版本中,由於它是向前兼容的,這意味着它支持與Elasticsearch的更高的版本進行通訊,而不是與其開發的版本進行通訊。java

6.0客戶端可以與任何6.x Elasticsearch節點通訊,而6.1客戶端確定可以與6.1,6.2和任何更高版本的6.x版本通訊,可是,若是6.1客戶端支持6.0節點不知道的某些API的新請求主體字段,則在與先前的Elasticsearch節點版本通訊時可能存在不兼容問題,例如在6.1和6.0之間。web

建議在將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.htmljson

Maven倉庫

高級別Java REST客戶端託管在Maven Central上,所需的最低Java版本爲1.8segmentfault

High Level REST Client與Elasticsearch具備相同的發佈週期,將版本替換爲想要的客戶端版本。api

若是你正在尋找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文件中:elasticsearch

dependencies {
    compile 'org.elasticsearch.client:elasticsearch-rest-high-level-client:6.4.2'
}

Lucene Snapshot倉庫

任何主要版本(如測試版)的最新版本可能都是基於Lucene Snapshot版本構建的,在這種狀況下,你將沒法解析客戶端的Lucene依賴關係。

例如,若是要使用依賴於Lucene 7.0.0-snapshot-00142c96.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來控制哪一個節點接收請求,有關自定義選項的更多示例,請參閱低級別客戶端文檔。

二、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提供的操做類型:能夠爲createupdate(默認)。
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) {
        
    }
}

三、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) {
        
    }
}

引起的異常表示返回了版本衝突錯誤。

四、Exists API

若是文檔存在,則existsAPI返回true,不然返回false

Exists請求

它就像Get API同樣使用GetRequest,支持全部可選參數,因爲exists()只返回truefalse,咱們建議關閉獲取_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失敗時調用。

五、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

六、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

相關文章
相關標籤/搜索