Elastic Search Javaアプリ

19599 ワード

前言
前の文ではElastic Search操作インデックスのReset Appiについて述べました。実際にElastic SearchのReset Appはすべての操作インターフェースを提供しています。プログラミング言語ではResearchをそのまま使うことができますが、Elastic Searchのすべての機能を呼び出すことができます。しかし、非常に不便で直感的なので、Elastic Search公式も多くの言語にアクセスするApiインターフェースを提供しています。公式に提供されているプログラミング言語インターフェースは、
  • Java
  • JavaScript
  • Grouvy
  • PHP
  • .NET
  • Perl
  • Python
  • Ruby
  • 同時にプログラミングコミュニティも大量のプログラミング言語のAppを提供しました。現在は主に
  • B 4 J
  • Clojure
  • ColdFsion(CFML)
  • エラン
  • Go
  • Grouvy
  • ハスキー
  • Java
  • JavaScript
  • kotlin
  • Lua
  • .NET
  • OCaml
  • Perl
  • PHP
  • Python
  • R
  • Ruby
  • Rust
  • Scara
  • Smalltalk
  • Vert.x
  • 普段はJavaで開発しています。そこで、Elastic SearchのJavaアプリの使い方についてお話しします。
    準備工作
    Javaアプリの機能を説明するために、シーンを準備しました。ここでは、いくつかのフィールドが記述されていると仮定します。私たちは名前、年齢、説明中のキーワードを通じて作者を調べます。
    ここでは、プログラムは主にJUnitのテストケースで動作しますので、まずJUnitの依存性を導入しました。
    
        junit
        junit
        4.12
        test
    
    
    Javaアプリの概要
    Elastic SearchはオフィシャルJavaアプリを提供します。ここには二つの種類があります。一つはLow Level Resit ApiとHigh Leve Reset Apiです。
    低レベルAppというのは機能が弱いわけではなく、Appが下の層に近い実現をしているということです。公式に提供されている低レベルアプリはオリジナルのReset Appの第1層パッケージです。Http呼び出しの詳細をパッケージ化するだけです。プログラムは、自分でクエリーの条件文字列を組み、解析して返した結果、json文字列などです。http契約の各種方法、協議の第一内容も処理します。
    高度なappiは、低レベルのappi上でのさらなるパッケージであり、インタフェースの方法、プロトコルヘッドを気にすることなく、人工的に起動されたパラメータ文字列を組み合わせることなく、返信されたjson文字列に対して一定の解析がある。使うほうが便利です。しかし、高級アプリはすべての低レベルアプリで実現される機能を実現していません。このような場合は、低レベルアプリを利用して自分の機能を実現する必要があります。
    第三者のJavaクライアントはコミュニティが自分で開発したElastic Searchクライアントです。公式はGitHub上の二つのオープンソースのプロジェクトFlumi、Jestに言及しました。
    Java Low Level Reset Api使用説明
    低レベルアプリの利点は、依存する他のライブラリが非常に少なく、機能も充実していることです。欠点はパッケージがあまり高級ではないので、使うのがまだとても煩雑です。私たちはまず、低級なアプリはどうやって使うかを見てみます。
    依存を導入
    前に建設されたMaven Javaプロジェクトでは、Elastic Searchの低レベルアプリを使用するには、まず低レベルアプリの依存を導入する必要があります。次のように
    
        org.elasticsearch.client
        elasticsearch-rest-client
        6.1.1
    
    
    クライアントを作成
    RestClient restClient = RestClient.builder(
            new HttpHost("localhost", 9200, "http"),
            new HttpHost("localhost", 9201, "http")).build();
    
    私たちはRestClientオブジェクトの静的方法builderとBrilderを通じてElastic SearchのResearchクライアントを作成します。ここでhostsは、Elastic Custerクラスタのノードのip、ポート、プロトコルを指定する可変パラメータである。
    メソッドの呼び出し
    クライアントが確立された後、二つの方法でRest Appを呼び出します。クラスは同期呼び出しで、クラスは非同期呼び出しです。
    同期コール
    同期コールの主な方法は以下の通りです。
    public Response performRequest(String method, String endpoint, Header... headers) throws IOException
    
    public Response performRequest(String method, String endpoint, Map params, Header... headers) throws IOException
    
    public Response performRequest(String method, String endpoint, Map params,
                                       HttpEntity entity, Header... headers) throws IOException
    
    
    これは三つの重負荷の方法であり、パラメータmethodはRestt Appiの方法を表しています。例えば、PUT、GET、POST、DELETEなどです。パラメータendpointは、Restt Appiパラメータのアドレスを表し、Reset AppiのURLのip:portフィールドの後から開始します。paramsは、urlパラメータ形式で伝達されるパラメータである。entityはhttp bodyを通じて伝達されるパラメータです。headersは可変パラメータであり、対応するhttpヘッダ情報を入力することができる。
    例えば、インデックスauthor_を確認したいです。testの情報は下記のコードで取得できます。
    Response response = restClient.performRequest("GET", "/author_test");
    
    たとえば、私たちはインデックスauthorを確認したいです。test中のdesフィールドにはソフトウェアの文書情報が含まれています。以下のコードで取得できます。
    String queryJson = "{
    " + " \"query\": {
    " + " \"match\": {
    " + " \"des\": \" \"
    " + " }
    " + " }
    " + "}"; Response response = restClient.performRequest("POST", "/author_test/_search", new HashMap(), new NStringEntity(queryJson,ContentType.APPLICATION_JSON));
    非同期呼び出し
    非同期呼び出しと同期呼び出しのパラメータは同じですが、非同期呼び出しは戻り値ではなく、パラメータの中にReponseListenerコールオブジェクトがあります。呼び出しが完了したら自動的に呼び出します。このコールバックはインターフェースで、プログラマが自分で実現する必要があります。
    非同期呼び出しの方法は以下の通りです。
    public void performRequestAsync(String method, String endpoint, ResponseListener responseListener, Header... headers)
    
    public void performRequestAsync(String method, String endpoint, Map params,
                                        ResponseListener responseListener, Header... headers)
    
    public void performRequestAsync(String method, String endpoint, Map params,
                                        HttpEntity entity, ResponseListener responseListener, Header... headers) 
    
    例えば、私は非同期でauthor_を調べたいです。testインデックスにdesに「ソフトウェア」のすべてのドキュメントが含まれている場合、コードは以下のようになります。
    String queryJson = "{
    " + " \"query\": {
    " + " \"match\": {
    " + " \"des\": \" \"
    " + " }
    " + " }
    " + "}"; restClient.performRequestAsync("POST", "/author_test/_search", new HashMap(), new NStringEntity(queryJson, ContentType.APPLICATION_JSON), new ResponseListener() { public void onSuccess(Response response) { try { String responseData = readResposne(response); System.out.println("******* search success ******"); System.out.println(responseData); } catch (Exception e) { e.printStackTrace(); } } public void onFailure(Exception exception) { exception.printStackTrace(); } });
    Java High Level Reset App使用説明
    Elastic SearchのJava高級Appは、低級なAppに比べて抽象度が高い。でも、個人的にはまだ難しいと思います。また、アドバンスアプリはすべてのReset Appの機能をサポートしていません。公式には高級アプリがサポートする機能リストがあります。ここから見ると、お問い合わせだけすれば、高級アプリのインターフェースで十分です。
    依存を導入
    前に建設されたMaven Javaプロジェクトでは、Elastic Searchの低レベルアプリを使用するには、まず低レベルアプリの依存を導入する必要があります。次のように
    
        org.elasticsearch.client
        elasticsearch-rest-high-level-client
        6.1.1
    
    
    クライアントを作成
    RestHighLevelClient client = new RestHighLevelClient(
            RestClient.builder(
                    new HttpHost("localhost", 9200, "http"),
                    new HttpHost("localhost", 9201, "http")));
    
    低レベルインターフェースと同様に、まずRetsClientオブジェクトの静的方法builder法によってRets Client Buiderオブジェクトを作成し、RestHighLevel Clidentオブジェクトの構築関数のパラメータとして、新しい上位クライアントオブジェクトを作成します。ここでhostsは、Elastic Custerクラスタのノードのip、ポート、プロトコルを指定する可変パラメータである。
    メソッドの呼び出し
    ここでは、低レベルインターフェースにおける最初のクエリの機能を実現するために、高級インターフェースを使用する。コードは以下の通りです
    SearchRequest searchRequest = new SearchRequest("author_test");
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    sourceBuilder.query(QueryBuilders.matchQuery("des", "  "));
    sourceBuilder.from(0);
    sourceBuilder.size(5);
    searchRequest.source(sourceBuilder);
    SearchResponse response = restClient.search(searchRequest);
    
    他のインターフェースの呼び出しは、対応するアプリドキュメントの説明を検索して完了します。
    完全コード
    最後の章は完全なコードを貼り付けます。
    初期化コード
    この部分のコードはテストの索引と索引ドキュメントの初期化を担当しています。注意したいのですが、Elastic Searchは準リアルタイムのシステムだと前に述べましたので、ドキュメントをインデックスし終わったら、すぐに調べたら、データが見つからないかもしれません。少し遅れが必要です。
    package com.x9710.es.test;
    
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpHost;
    import org.apache.http.entity.ContentType;
    import org.apache.http.nio.entity.NStringEntity;
    import org.elasticsearch.client.RestClient;
    import org.elasticsearch.client.RestHighLevelClient;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    
    public class IndexInitUtil {
        public RestClient initLowLevelClient() {
            //    ip 、port       Elastic Search    
            RestClient restClient = RestClient.builder(
                    new HttpHost("10.110.2.53", 9200, "http")).build();
    
    
            try {
                initIndex(restClient);
    
            } catch (Exception e) {
                e.printStackTrace();
            }
            return restClient;
        }
    
        public RestHighLevelClient initHighLevelClient() {
            //    ip 、port       Elastic Search    
            RestHighLevelClient highLevelClient = new RestHighLevelClient(
                    RestClient.builder(
                            new HttpHost("10.110.2.53", 9200, "http"))
            );
    
            RestClient restClient = RestClient.builder(
                    new HttpHost("10.110.2.53", 9200, "http")).build();
    
            try {
                initIndex(restClient);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    restClient.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    
    
            return highLevelClient;
        }
    
        private void initIndex(RestClient restClient) {
    
            String authIndexDefine = "{
    " + "\t\"settings\" : {
    " + " \"index\" : {
    " + " \"number_of_shards\" : 6,
    " + " \"number_of_replicas\" : 0
    " + " }
    " + " },
    " + " \"mappings\": {
    " + " \"doc\": {
    " + " \"properties\": {
    " + " \t\"id\": {\"type\": \"text\"},
    " + " \"name\": {\"type\": \"text\"},
    " + " \"sex\": {\"type\": \"text\"},
    " + " \"age\": {\"type\": \"integer\"},
    " + " \"des\":{
    " + " \t\"type\":\"text\",
    " + " \t\"analyzer\": \"ik_max_word\",
    " + "\t\t\t\t\t\"search_analyzer\": \"ik_max_word\"
    " + " }
    " + " }
    " + " }
    " + " }
    " + "}"; HttpEntity authorIndexEntity = new NStringEntity(authIndexDefine, ContentType.APPLICATION_JSON); // author List authorDocs = new ArrayList(); authorDocs.add(new NStringEntity(" {
    " + "\t\"id\":\"A1001\",
    " + "\t\"name\":\" \",
    " + "\t\"age\":24,
    " + "\t\"sex\":\" \",
    " + "\t\"des\":\"IT , Java \"
    " + " }", ContentType.APPLICATION_JSON)); authorDocs.add(new NStringEntity(" {
    " + "\t\"id\":\"A1002\",
    " + "\t\"name\":\" \",
    " + "\t\"age\":47,
    " + "\t\"sex\":\" \",
    " + "\t\"des\":\"IT , \"
    " + " }", ContentType.APPLICATION_JSON)); try { // author_test restClient.performRequest("PUT", "/author_test", new HashMap(), authorIndexEntity); // author_index for (int i = 0; i < authorDocs.size(); i++) { restClient.performRequest("POST", "/author_test/doc", new HashMap(), authorDocs.get(i)); } // , , Thread.currentThread().sleep(1000); } catch (Exception e) { e.printStackTrace(); } } }
    低レベルAppテストサンプル例
    package com.x9710.es.test;
    
    import org.apache.http.entity.ContentType;
    import org.apache.http.nio.entity.NStringEntity;
    import org.codehaus.jettison.json.JSONObject;
    import org.elasticsearch.client.Response;
    import org.elasticsearch.client.ResponseListener;
    import org.elasticsearch.client.RestClient;
    import org.junit.After;
    import org.junit.Assert;
    import org.junit.Before;
    import org.junit.Test;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.HashMap;
    
    /**
     * Elastic Search    Api    
     *
     * @author    
     * @since 2018-01-11
     */
    public class LowLeveApiTest {
        RestClient restClient = null;
    
        @Before
        public void before() {
            restClient = new IndexInitUtil().initLowLevelClient();
        }
    
        @Test
        public void testLocateAuthorIndex() {
            try {
                Response response = restClient.performRequest("GET", "/author_test");
                String responseData = readResposne(response);
                Assert.assertTrue(new JSONObject(responseData).has("author_test"));
                System.out.println(responseData);
            } catch (Exception e) {
                e.printStackTrace();
                Assert.assertTrue(false);
            }
        }
    
    
        @Test
        public void testQueryAuthDoc() {
            try {
                String queryJson = "{
    " + " \"query\": {
    " + " \"match\": {
    " + " \"des\": \"Java\"
    " + " }
    " + " }
    " + "}"; Response response = restClient.performRequest("POST", "/author_test/_search", new HashMap(), new NStringEntity(queryJson, ContentType.APPLICATION_JSON)); String responseData = readResposne(response); JSONObject responseJson = new JSONObject(responseData); Assert.assertTrue(responseJson.has("hits") && responseJson.getJSONObject("hits").getInt("total") == 1); System.out.println(responseData); } catch (Exception e) { e.printStackTrace(); Assert.assertTrue(false); } } @Test public void testQueryAuthDocAsy() { try { String queryJson = "{
    " + " \"query\": {
    " + " \"match\": {
    " + " \"des\": \" \"
    " + " }
    " + " }
    " + "}"; restClient.performRequestAsync("POST", "/author_test/_search", new HashMap(), new NStringEntity(queryJson, ContentType.APPLICATION_JSON), new ResponseListener() { public void onSuccess(Response response) { try { String responseData = readResposne(response); System.out.println("******* search success ******"); System.out.println(responseData); } catch (Exception e) { e.printStackTrace(); } } public void onFailure(Exception exception) { exception.printStackTrace(); } }); } catch (Exception e) { e.printStackTrace(); Assert.assertTrue(false); } } @After public void after() { try { if (restClient != null) { restClient.performRequest("DELETE", "/author_test"); } } catch (Exception e) { e.printStackTrace(); } finally { if (restClient != null) { try { restClient.close(); } catch (Exception e) { e.printStackTrace(); } } } } private String readResposne(Response response) throws Exception { BufferedReader brd = new BufferedReader(new BufferedReader(new InputStreamReader(response.getEntity().getContent()))); String line; StringBuilder respongseContext = new StringBuilder(); while ((line = brd.readLine()) != null) { respongseContext.append(line).append("
    "); } //rd.close(); if (respongseContext.length() > 0) { respongseContext.deleteCharAt(respongseContext.length() - 1); } return respongseContext.toString(); } }
    高級Appテストサンプル例
    package com.x9710.es.test;
    
    import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
    import org.elasticsearch.action.search.SearchRequest;
    import org.elasticsearch.action.search.SearchResponse;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.elasticsearch.index.query.QueryBuilders;
    import org.elasticsearch.search.builder.SearchSourceBuilder;
    import org.junit.After;
    import org.junit.Assert;
    import org.junit.Before;
    import org.junit.Test;
    
    /**
     * Elastic Search    Api    
     *
     * @author    
     * @since 2018-01-11
     */
    public class HighLevelApiTest {
        RestHighLevelClient restClient = null;
    
        @Before
        public void before() {
            restClient = new IndexInitUtil().initHighLevelClient();
        }
    
    
        @Test
        public void testQueryAuthDoc() {
            try {
    SearchRequest searchRequest = new SearchRequest("author_test");
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    sourceBuilder.query(QueryBuilders.matchQuery("des", "  "));
    sourceBuilder.from(0);
    sourceBuilder.size(5);
    searchRequest.source(sourceBuilder);
    SearchResponse response = restClient.search(searchRequest);
                Assert.assertTrue(response.getHits().getTotalHits() == 2);
                System.out.println(response.toString());
            } catch (Exception e) {
                e.printStackTrace();
                Assert.assertTrue(false);
            }
        }
    
    
        @After
        public void after() {
            try {
                if (restClient != null) {
                    restClient.indices().deleteIndex(new DeleteIndexRequest("author_test"));
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (restClient != null) {
                    try {
                        restClient.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
    後記
    前にも述べましたが、コミュニティはElastic Searchのクライアントライブラリにも多く貢献していますが、研究する時間がありません。もし誰かが使ったら使いやすいと思います。勧めてください。