SearchRequest
用於與搜索文檔、聚合、suggestions相關的任何操做,還提供了在結果文檔上請求高亮的方法。編程
在最基本的表單中,咱們能夠向請求添加查詢:segmentfault
SearchRequest searchRequest = new SearchRequest(); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(QueryBuilders.matchAllQuery()); searchRequest.source(searchSourceBuilder);
SeachRequest
,沒有參數,這將針對全部索引運行。SearchSourceBuilder
中,它爲搜索請求body中的全部內容提供了setter。match_all
查詢添加到SearchSourceBuilder
。SearchSourceBuilder
添加到SeachRequest
。咱們先來看一下SearchRequest
的一些可選參數:數組
SearchRequest searchRequest = new SearchRequest("posts"); searchRequest.types("doc");
還有一些其餘有趣的可選參數:異步
searchRequest.routing("routing");
searchRequest.indicesOptions(IndicesOptions.lenientExpandOpen());
IndicesOptions
控制如何解析不可用的索引以及如何擴展通配符表達式。searchRequest.preference("_local");
控制搜索行爲的大多數選項均可以在SearchSourceBuilder
上設置,它包含或多或少與Rest API的搜索請求body中等效的選項。ide
如下是一些常見選項的幾個示例:函數
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
。size
選項,默認爲10
。在此以後,只需將SearchSourceBuilder
添加到SearchRequest
:post
SearchRequest searchRequest = new SearchRequest(); searchRequest.indices("posts"); searchRequest.source(sourceBuilder);
使用QueryBuilder
對象建立搜索查詢,QueryBuilder存在對於Elasticsearch的查詢DSL支持的每種搜索查詢類型。性能
可使用其構造函數建立QueryBuilder
:fetch
MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("user", "kimchy");
建立後,QueryBuilder
對象提供了配置其建立的搜索查詢選項的方法:ui
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
輔助方法。
SearchSourceBuilder
容許添加一個或多個SortBuilder
實例,有四種特殊的實現(Field-,Score-,GeoDistance-和ScriptSortBuilder)。
sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC)); sourceBuilder.sort(new FieldSortBuilder("_uid").order(SortOrder.ASC));
_score
降序排序(默認值)。_id
字段進行升序排序。默認狀況下,搜索請求會返回文檔_source
的內容,但與Rest API中的內容同樣,你能夠覆蓋此行爲,例如,你能夠徹底關閉_source
檢索:
sourceBuilder.fetchSource(false);
該方法還接受一個或多個通配符模式的數組,以控制以更精細的方式包含或排除哪些字段:
String[] includeFields = new String[] {"title", "user", "innerObject.*"}; String[] excludeFields = new String[] {"_type"}; sourceBuilder.fetchSource(includeFields, excludeFields);
經過在SearchSourceBuilder
上設置HighlightBuilder
,能夠實現高亮搜索結果,經過將一個或多個HighlightBuilder.Field
實例添加到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
。title
字段建立字段高光色。Rest API文檔中有許多選項須要詳細說明,Rest API參數(例如pre_tags
)一般由具備類似名稱的setter更改而來(例如#preTags(String ...)
)。
稍後能夠從SearchResponse
中檢索高亮的文本片斷。
能夠經過先建立適當的AggregationBuilder
而後在SearchSourceBuilder
上設置聚合來將聚合添加到搜索中,在如下示例中,咱們在公司名稱上建立terms
聚合 ,使用子聚合在公司員工平均年齡上:
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); TermsAggregationBuilder aggregation = AggregationBuilders.terms("by_company") .field("company.keyword"); aggregation.subAggregation(AggregationBuilders.avg("average_age") .field("age")); searchSourceBuilder.aggregation(aggregation);
構建聚合頁面提供了全部可用的聚合的列表及其對應的AggregationBuilder
對象和AggregationBuilders
輔助方法。
稍後咱們將看到如何訪問SearchResponse
中的聚合。
要向搜索請求添加建議,請使用從SuggestBuilders
工廠類中可輕鬆訪問的SuggestionBuilder
的實現之一,Suggestion構建器須要添加到頂級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);
user
字段和文本kmichy
建立一個新的TermSuggestionBuilder
。suggest_user
。咱們稍後將看到如何從SearchResponse
中檢索suggestion。
分析API可用於分析特定搜索請求的查詢和聚合的執行狀況,爲了使用它,必須在SearchSourceBuilder
上將profile
標誌設置爲true
:
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.profile(true);
執行SearchRequest
後,相應的SearchResponse
將包含分析結果。
如下列方式執行SearchRequest
時,客戶端在繼續執行代碼以前等待返回SearchResponse
:
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
執行SearchRequest
也能夠以異步方式完成,以便客戶端能夠直接返回,用戶須要經過將請求和監聽器傳遞給異步搜索方法來指定響應或潛在的故障如何處理:
client.searchAsync(searchRequest, RequestOptions.DEFAULT, listener);
SearchRequest
和執行完成時要使用的ActionListener
。異步方法不會阻塞而且當即返回,完成後,若是執行成功完成則使用onResponse
方法回調ActionListener
,若是失敗則使用onFailure
方法。
SearchResponse
的典型監聽器以下所示:
ActionListener<SearchResponse> listener = new ActionListener<SearchResponse>() { @Override public void onResponse(SearchResponse searchResponse) { } @Override public void onFailure(Exception e) { } };
onResponse
:執行成功完成時調用。onFailure
:在整個SearchRequest
失敗時調用。經過執行搜索返回的SearchResponse
提供有關搜索執行自己以及對返回文檔的訪問的詳細信息,首先,有關於請求執行自己的有用信息,例如HTTP狀態碼,執行時間或請求是提早終止仍是超時:
RestStatus status = searchResponse.status(); TimeValue took = searchResponse.getTook(); Boolean terminatedEarly = searchResponse.isTerminatedEarly(); boolean timedOut = searchResponse.isTimedOut();
其次,響應還經過提供有關搜索影響的碎片總數以及成功與不成功碎片的統計信息的碎片級別執行的信息,能夠經過在ShardSearchFailures
上迭代數組來處理可能的失敗,以下例所示:
int totalShards = searchResponse.getTotalShards(); int successfulShards = searchResponse.getSuccessfulShards(); int failedShards = searchResponse.getFailedShards(); for (ShardSearchFailure failure : searchResponse.getShardFailures()) { // failures should be handled here }
要訪問返回的文檔,咱們須要先獲取響應中包含的SearchHits
:
SearchHits hits = searchResponse.getHits();
SearchHits
提供有關全部匹配的全局信息,例如總命中數或最高分數:
long totalHits = hits.getTotalHits(); float maxScore = hits.getMaxScore();
嵌套在SearchHits
中的是能夠迭代的單個搜索結果:
SearchHit[] searchHits = hits.getHits(); for (SearchHit hit : searchHits) { // do something with the SearchHit }
SearchHit
提供對每一個搜索命中的索引、類型、docId和分數等基本信息的訪問:
String index = hit.getIndex(); String type = hit.getType(); 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");
若是須要,能夠從結果中的每一個SearchHit
檢索高亮的文本片斷,命中對象提供對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(); }
title
字段的高亮。能夠從SearchResponse
檢索聚合,先獲取聚合樹的根,Aggregations
對象,而後按名稱獲取聚合。
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
的terms
聚合。Elastic
鍵入的桶。average_age
子聚合。請注意,若是按名稱訪問聚合,則須要根據所請求的聚合類型指定聚合接口,不然將引起ClassCastException
:
Range range = aggregations.get("by_company");
terms
聚合,但咱們嘗試將其做爲range
聚合進行檢索。還能夠將全部聚合做爲由聚合名稱鍵入的映射進行訪問,在這種狀況下,須要顯式地進行到正確聚合接口的轉換:
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(); } }
要從SearchResponse
獲取suggestions,請使用Suggest
對象做爲入口點,而後檢索嵌套的suggestion對象:
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
類訪問suggestions。TermSuggestion
),不然拋出ClassCastException
。使用getProfileResults()
方法從SearchResponse
檢索分析結果,此方法返回包含SearchSquest
執行中涉及的每一個碎片的ProfileShardResult
對象的Map
,ProfileShardResult
使用惟一標識分析結果對應的碎片的鍵存儲在Map
中。
下面是一個示例代碼,顯示如何迭代每一個碎片的全部分析結果:
Map<String, ProfileShardResult> profilingResults = searchResponse.getProfileResults(); for (Map.Entry<String, ProfileShardResult> profilingResult : profilingResults.entrySet()) { String key = profilingResult.getKey(); ProfileShardResult profileShardResult = profilingResult.getValue(); }
SearchResponse
中檢索ProfileShardResult
的Map
。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(); }
Rest API文檔包含有關分析查詢的更多信息以及查詢分析信息的說明。
QueryProfileShardResult
還能夠訪問Lucene收集器的分析信息:
CollectorResult collectorResult = queryProfileResult.getCollectorResult(); String collectorName = collectorResult.getName(); Long collectorTimeInMillis = collectorResult.getTime(); List<CollectorResult> profiledChildren = collectorResult.getProfiledChildren();
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
。Rest API文檔包含有關分析聚合的更多信息。