ElasticSearch【2】搜索API
如下為一段帶有分頁的簡單搜索查詢示例
在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