1. 程式人生 > >elasticsearch java API ------搜尋

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()取得結果中進行了高亮標識的域名-域值對,然後對這些域名-域值對進行分析得到高亮的域結果。