1. 程式人生 > >ElasticSearch【2】搜索API

ElasticSearch【2】搜索API

高亮顯示 命中 gets 獲得 value com 超時 desc elastics

如下為一段帶有分頁的簡單搜索查詢示例

在search搜索中大部分的搜索條件添加都可通過設置SearchSourceBuilder來實現,然後將SearchSourceBuilder

RestHighLevelClient client = ElasticClient.getRestHighLevelClient();
SearchRequest searchRequest = new SearchRequest();
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.termQuery(
"user", "kimchy")); sourceBuilder.from(0); sourceBuilder.size(5); sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); //設置一個可選的超時,控制允許搜索的時間 searchRequest.source(sourceBuilder); try { SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT); Long total = search.getHits().getTotalHits(); //
獲取匹配的總數量 System.out.println("總記錄數:" + total); for (SearchHit hit : search.getHits().getHits()) { float score = hit.getScore(); //獲得分數,即匹配度 String source = hit.getSourceAsString(); System.out.println(source); } } catch (IOException e) { e.printStackTrace(); }

search查詢的返回值為SearchResponse,調用SearchResponse的getHits()方法會獲取SearchHits對象,然後再通過SearchHits的getHits()方法即返回一個SearchHit[]數組。

遍歷SearchHit[]數組獲取每一個對象,通過hit.getScore()可獲取分數,即搜索匹配度。通過hit.getSourceAsString()可得到對象的json字符串。

備註:在上述查詢中用到了termQuery查詢,ES還提供了matchQuery查詢,不同的查詢需求中需要選擇不同的查詢,在此需要了解這兩個查詢的區別:

  • termQuery : term為不使用分詞器查找,類似精確查找。
  • matchQuery : mactch為使用分詞器進行查找,會查詢到一些近似匹配的內容。

SearchHit使用匯總

要獲取返回的內容,需要獲得SearchHit,下面總結下SearchHit的一些使用:

SearchHits hits = searchResponse.getHits();
long totalHits = hits.getTotalHits(); //查詢命中總數
float maxScore = hits.getMaxScore(); //查詢命中的最高分數
//嵌套在SearchHits可以叠代獲取單個搜索結果中
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
    //使用SearchHit做一些事情
}
//通過SearchHit還可以獲取 返回數據 的索引、類型、docId和得分等基本信息
String index = hit.getIndex(); 
String type = hit.getType();
String id = hit.getId();
float score = hit.getScore();
//hit還可以以Json字符串或Map的形式返回數據
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");

指定排序

sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC)); //按分數(即匹配度)排序
sourceBuilder.sort(new FieldSortBuilder("_uid").order(SortOrder.ASC)); //通過指定字段來排序

排序有兩種排序方式,第一通過ScoreSortBuilder實現按分數(即匹配度)排序

第二種方式通過指定字段來排序,如上圖所示通過“_uid”字段排序

關閉檢索

有時候我們只想要知道到底匹配了多少條具體,但不關系具體每條記錄的內容,這個時候我們可以選擇關閉檢索,不去查詢每天數據的內容,可通過如下方式實現:

sourceBuilder.fetchSource(false);

關閉檢索後,運行程序輸出如下

技術分享圖片

只返回了總記錄數,遍歷輸出每條數據均為 null

另外還可以通過sourceBuilder接受一個或多個數組,來控制要要返回哪些字段,排除哪些字段。具體實現如下,第一個數組參數為要接受的字段,第二個數組參數為要排除的內容:

String[] includeFields = new String[] {"title", "user", "innerObject.*"};
String[] excludeFields = new String[] {"_type"};
sourceBuilder.fetchSource(includeFields, excludeFields);

高亮顯示

通過向SearchSourceBuilder添加HighlightBuilder示例可添加高亮顯示功能

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
HighlightBuilder highlightBuilder = new HighlightBuilder(); 
HighlightBuilder.Field highlightTitle = new HighlightBuilder.Field("title"); 
highlightTitle.highlighterType("unified"); //字段高亮顯示類型,默認用標簽包裹高亮字詞
highlightBuilder.field(highlightTitle);
searchSourceBuilder.highlighter(highlightBuilder);

以上只是在查詢中加入高亮顯示的功能,那麽我們如何在查詢結果中獲取呢,通過SearchHit的getHighlightFields()方法獲取我們需要關鍵內容:

SearchHits hits = searchResponse.getHits();
for (SearchHit hit : hits.getHits()) {
    Map highlightFields = hit.getHighlightFields();
    HighlightField highlight = highlightFields.get("title"); 
    Text[] fragments = highlight.fragments();  
    String fragmentString = fragments[0].string();
}

ElasticSearch【2】搜索API