elasticsearch java API ------搜尋
在建立索引時,我們根據IndexResponse,得到了index、type和id,Get一條記錄的方法很簡單:
GetResponse getResponse = client.prepareGet(index, type, id).execute().actionGet();
分散式搜尋Elasticsearch——建立索引一文中提到如何將一個實體轉化為Json字串,我們推薦的方法是使用Jackson,那麼,在Get得到Response後,也使用Jackson將Json字串轉化為你的實體:簡單的搜尋:Person newPerson = mapper.readValue(getResponse.getSourceAsString(), Person.class);
SearchResponse response = client.prepareSearch("user") .setTypes("tb_person0", "tb_person1", "tb_person2", "tb_person3", "tb_person4") .setSearchType(SearchType.DFS_QUERY_THEN_FETCH) .setQuery(QueryBuilders.fieldQuery("name", "張三")) // Query .setFilter(FilterBuilders.rangeFilter("age").from(20).to(22)) // Filter .setFrom(0).setSize(60).setExplain(true) .execute() .actionGet(); SearchHits hits = response.getHits(); for (SearchHit hit : hits) { String json = hit.getSourceAsString(); Person newPerson = mapper.readValue(json, Person.class); System.out.println("namett" + newPerson.getName()); System.out.println("sextt" + newPerson.getSex()); System.out.println("agett" + newPerson.getAge()); System.out.println("isStudenttt" + newPerson.getIsStudent()); }
client.prepareSearch用來建立一個SearchRequestBuilder,搜尋即由SearchRequestBuilder執行。client.prepareSearch方法有引數為一個或多個index,表現在資料庫中,即零個或多個數據庫名,你既可以使用:
client.prepareSearch().setIndices("index1","index2","index3","index4");
也可以使用以下方式取代:
client.prepareSearch("index1","index2","index3","index4");
SearchRequestBuilder有很多很實用的方法:
(1) setIndices(String... indices):上文中描述過,引數可為一個或多個字串,表示要進行檢索的index;
(2) setTypes(String... types):引數可為一個或多個字串,表示要進行檢索的type,當引數為0個或者不呼叫此方法時,表示查詢所有的type;
(3) setSearchType(SearchType searchType):執行檢索的類別,值為org.elasticsearch.action.search.SearchType的元素,SearchType是一個列舉型別的類,其值如下所示:
元素 | 含義 |
QUERY_THEN_FETCH |
查詢是針對所有的塊執行的,但返回的是足夠的資訊,而不是文件內容(Document)。 結果會被排序和分級,基於此,只有相關的塊的文件物件會被返回。由於被取到的僅僅是這些, 故而返回的hit的大小正好等於指定的size。這對於有許多塊的index來說是很便利的 (返回結果不會有重複的,因為塊被分組了)。 |
QUERY_AND_FETCH |
最原始(也可能是最快的)實現就是簡單的在所有相關的shard上執行檢索並返回結果 。每個shard返回一定尺寸的結果。由於每個shard已經返回了一定尺寸的hit, 這種型別實際上是返回多個shard的一定尺寸的結果給呼叫者。 |
DFS_QUERY_THEN_FETCH |
與QUERY_THEN_FETCH相同 ,預期一個初始的散射相伴用來為更準確的score計算分配了的term頻率。 |
DFS_QUERY_AND_FETCH |
與QUERY_AND_FETCH相同 ,預期一個初始的散射相伴用來為更準確的score計算分配了的term頻率。 |
SCAN |
在執行了沒有進行任何排序的檢索時執行瀏覽 。此時將會自動的開始滾動結果集。 |
COUNT | 只計算結果的數量,也會執行facet。 |
(4) setSearchType(String searchType),與setSearchType(SearchType searchType)類似,區別在於其值為字串型的SearchType,值可為dfs_query_then_fetch、dfsQueryThenFetch、dfs_query_and_fetch、dfsQueryAndFetch、query_then_fetch、queryThenFetch、query_and_fetch或queryAndFetch;
(5) setScroll(Scroll scroll)、setScroll(TimeValue keepAlive)和setScroll(String keepAlive),設定滾動,引數為Scroll時,直接用new Scroll(TimeValue)構造一個Scroll,為TimeValue或String時需要將TimeValue和String轉化為Scroll;
(6) setTimeout(TimeValue timeout)和setTimeout(String timeout),設定搜尋的超時時間;
(7) setQuery,設定查詢使用的Query;
(8) setFilter,設定過濾器;
(9) setMinScore,設定Score的最小數量;
(10) setFrom,從哪一個Score開始查;
(11) setSize,需要查詢出多少條結果;
除以上列舉的這些,SearchRequestBuilder還有很多方法,這些方法用於不同的場景,需要大家在實際使用中去體驗。
檢索出結果後,通過response..getHits()可以得到所有的SearchHit,得到Hit後,便可迭代Hit取到對應的Document,轉化成為需要的實體。 前面提到如何進行搜尋,並將SearchRequestBuilder的一些方法進行了列舉,本文呼叫了SearchRequestBuilder的用於高亮的方法,處理了檢索中的高亮問題:
SearchResponse response1 = client.prepareSearch("user")
.setTypes("tb_person0", "tb_person1", "tb_person2", "tb_person3", "tb_person4")
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
.setQuery(QueryBuilders.fieldQuery("name", "張三")) // Query
.addHighlightedField("name")
.setHighlighterPreTags("<span style="color:red">")
.setHighlighterPostTags("</span>")
.setFilter(FilterBuilders.rangeFilter("age").from(20).to(22)) // Filter
.setFrom(0).setSize(60).setExplain(true)
.execute()
.actionGet();
SearchHits hits1 = response1.getHits();
for(SearchHit hit : hits1){
String json = hit.getSourceAsString();
Person newPerson = mapper.readValue(json,
Person.class);
Map<String, HighlightField> result = hit.highlightFields();
HighlightField titleField = result.get("name");
Text[] titleTexts = titleField.fragments();
String name = "";
for(Text text : titleTexts){
name += text;
}
newPerson.setName(name);
System.out.println("namett" + newPerson.getName());
System.out.println("sextt" + newPerson.getSex());
System.out.println("agett" + newPerson.getAge());
System.out.println("isStudenttt" + newPerson.getIsStudent());
System.out.println("--------------------------");
}
addHighlightedField(String fieldName)指明要進行高亮處理的Field;setHighlighterPreTags設定了高亮文字的字首;setHighlighterPostTags設定了高亮文字的字尾。
取得hit後,使用hit.highlightFields()取得結果中進行了高亮標識的域名-域值對,然後對這些域名-域值對進行分析得到高亮的域結果。