1. 程式人生 > >使用Java Rest Client操作Elasticsearch

使用Java Rest Client操作Elasticsearch

Elasticsearch作為一個成熟的開源框架,對主流的多種客戶端語言都支援,比如Java,JavaScript ,PHP,.Net,Python,Ruby,CURL當然還有一些小眾的語言,雖然es官網沒支援,但是個人開發者也有一些開源的,具體的可在es官網clients地址檢視:

開發過程中,基本最常用的就是Java和curl的方式了,因為es本身就是使用java語言開發的,所以對Java的支援應該是最到位了,此外es也支援rest ful的DSL的訪問方式,我們可以在linux上輕鬆的使用curl命令來對es進行增刪改查,curl的操作方式大多數都是臨時的,實際開發的我們還是用程式語言來訪問的:

es支援Java API的訪問方式,支援非常全面,唯一的缺點就是依賴有點多,程式碼稍臃腫,有時候我們想簡單的開發一個非常小的功能,又不想使用java笨重的客戶端方式,應該怎麼辦?

上文說到es支援rest的訪問方式,那麼我們完全可以使用httpclient或者jsoup來直接傳送http請求不就行了嗎?其實是可以的,使用httpclient和jsoup來發送curl的命令也能操作es,獲取結果。這裡面有一個需要注意的地方。

httpclient和jsoup都不直接支援傳送DELETE方法帶引數的請求,這一點是個小缺陷,如果這個不支援,意味著一些刪除操作比如delete by query可能支援不太好。jsoup是完全不支援,而在httpclient裡面我們可以通過繼承重寫HttpEntityEnclosingRequestBase來滿足,刪除請求帶引數體,下面來看下如何使用:

繼承重寫的程式碼:

package tools;

import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;

import java.net.URI;

public class MyHttpDelete extends HttpEntityEnclosingRequestBase {
    //
    public static final String METHOD_NAME = "DELETE";
    //
    public String getMethod() {
        return METHOD_NAME;
    }
    //
public MyHttpDelete(final String uri) { super(); setURI(URI.create(uri)); } // public MyHttpDelete(final URI uri) { super(); setURI(uri); } // public MyHttpDelete() { super(); } }

然後使用httpclient傳送一個刪除請求:

//例項化http,刪除id=1001的一條資料
    val client = HttpClients.createDefault()
    val httpdelete = new MyHttpDelete("http://localhost:9200/test_index/logs/_query")
    val s = new StringEntity("{  \"query\": {   \"query_string\": {     \"query\":  id:1001    "       }  }} ",ContentType.APPLICATION_JSON)
    httpdelete.setEntity(s)
    val rs=client.execute(httpdelete)//執行刪除
    //解析響應結果
    val json = EntityUtils.toString(rs.getEntity(), "UTF-8")
    //釋放資源
    client.close()

httpclient還是比較強大的,但是上面的程式碼還是有點複雜,而且涉及連線的地方是有問題的,我們都知道es一般都是多臺機器組成叢集,而使用原生的httpclient請求建立的連結只能是某一臺機器的ip這樣一來,如果這臺機器掛掉這個客戶端程式就完全不能使用了,所以風險還是比較大的,不過也不用擔心,es官網也提供了ES Java RestClient的方式來訪問es,這個庫底層用的也是httpclient的元件,只不過es官網做了封裝,支援多機器ip,以及對請求方法做了簡化,所以想減少專案的依賴,又對支援功能要求比較健壯,我們就可以使用這個庫來開發我們的業務。

官網文件地址:

maven依賴:

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>rest</artifactId>
    <version>5.5.1</version>
</dependency>

下面來看下,如何使用ES的RestClient來操作ES:

//初始化RestClient例項
 static  RestClient restClient = RestClient.builder(
            new HttpHost("192.168.10.5", 9200, "http"),
            new HttpHost("192.168.10.6", 9200, "http"),
            new HttpHost("192.168.10.7", 9200, "http")).build()
            
     
  // (1) 執行一個基本的方法,驗證es叢集是否搭建成功
  
   Response response = restClient.performRequest("GET", "/", Collections.singletonMap("pretty", "true"));
        System.out.println(EntityUtils.toString(response.getEntity()));
        
  //輸出結果:
  {
  "name" : "nd2",
  "cluster_name" : "search",
  "version" : {
    "number" : "2.3.4",
    "build_hash" : "e455fd0c13dceca8dbbdbb1665d068ae55dabe3f",
    "build_timestamp" : "2016-06-30T11:24:31Z",
    "build_snapshot" : false,
    "lucene_version" : "5.5.0"
  },
  "tagline" : "You Know, for Search"
}
            
// (2)驗證es的某個索引是否存在

Response response = restClient.performRequest("HEAD","/product/pdt",Collections.<String, String>emptyMap());
        System.out.println(response.getStatusLine().getReasonPhrase().equals("OK"));
          
//輸出結果:

true



// (3) 刪除某個索引的指定條件的資料


  Map<String, String> paramMap = new HashMap<String, String>();
            paramMap.put("q", "id:"+id);
            paramMap.put("pretty", "true");
            Response response = restClient.performRequest("DELETE",  + "product/pdt/_query", paramMap);
            System.out.println(EntityUtils.toString(response.getEntity()));


//輸出結果:

{
  "took" : 0,
  "timed_out" : false,
  "_indices" : {
    "_all" : {
      "found" : 1,
      "deleted" : 0,
      "missing" : 0,
      "failed" : 0
    }
  },
  "failures" : [ ]
}

總結:

ES官網提供的RestClient還支援nio實現的非同步非阻塞的方式多執行緒多送請求,通過回撥函式來處理響應的結果,當然了許可權認證,超時中斷,失敗重試,執行緒數都有對應的設定選項,感興趣的朋友可自行查閱嘗試。

通過對比我們發現官網封裝的RestClient使用起來更加簡單和健壯,比起來沒有包裝的httpclient原生的方式更加符合生產環境的標準,對於不想熟悉標準的java api的es操作方法,又想通過java來訪問es的朋友們,RestClient是一個不錯的選擇。