天天看點

個人開源項目smart_elk_client

recommend

elastic search java用戶端,使用retrofit + rxjava2 溝通elk的rest端點進行索引,文檔和查詢相關操作。 使用簡單,支援elk多節點,支援響應式程式設計特性,适合脫離服務端單獨在android項目中使用。

quick start

  1. clone項目
git clone [email protected]:Tinysakura/smart_elk_client.git
           
  1. maven編譯
mvn clean install -Dmaven.test.skip=true
           
  1. pom中引入
<dependencies>
	<dependency>
            <groupId>com.tinysakura</groupId>
            <artifactId>smart_elk_client</artifactId>
            <version>1.0-RELEASE</version>
        </dependency>
</dependencies>
           

usage

1.配置elk節點

如果你是spring-boot或其他spring項目,在resource path下的application.properties或application.yml檔案中配置elk.node.ip屬性(推薦将主節點或可用性較高的節點放在首位,節點位址由,分隔):

elk.node.ip = http://192.168.1.1:9200,http://127.0.0.1:9200
           

如果是普通java項目,則需要在resource path下手動建立application.properties檔案。

2.建立索引

@Test
    public void createIndexTest() {
        IndexService indexService = RetrofitProxyServiceHolder.getInstance().getIndexServiceProxy();

        Analyzer.Builder analyzerBuilder = new Analyzer.Builder();
        Analyzer analyzer = analyzerBuilder.name("chinese").tokenizer("ik_max_word").build();

        Properties.Builder propBuilder = new Properties.Builder();
        Properties properties = propBuilder.name("author").type(DocumentPropertiesConstant.Type.TEXT).analyzer("ik_max_word").name("title").analyzer("ik_max_word").type(DocumentPropertiesConstant.Type.TEXT).build();
        
        DocumentType.Builder docBuilder = new DocumentType.Builder();
        DocumentType documentType = docBuilder.name("book").properties(properties).build();

        Index.Builder indexBuilder = new Index.Builder();
        Index index = indexBuilder.indexName("book").replicasNumber(1).shardsNumber(4).analysis(analyzer).mapping(documentType).build();

        indexService.createIndex(index.getIndexName(), index.getIndex()).subscribe(new Consumer<Acknowledged>() {
            @Override
            public void accept(Acknowledged acknowledged) throws Exception {
                System.out.println(acknowledged);
            }
        });
    }
           

首先從RetrofitProxyServiceHolder這個單例類中擷取索引操作相關的IndexService代理對象,之後使用構造器類自定義分析器、映射配置、索引配置,最後使用indexService的createIndex方法建立索引。構造器的設計遵循elk的rest api,所有構造器類都位于項目的com.tinysakura.core包下,使用者可以參考源碼和elk的rest api進行使用。

3 為索引添加文檔

3.1 單個文檔的索引

@Test
    public void addDocumentTest() {
        DocumentService documentService = RetrofitProxyServiceHolder.getInstance().getDocumentServiceProxy();

        Book book = new Book();
        book.setTitle("冰與火之歌");
        book.setAuthor("喬治·馬丁");

        documentService.postDocument("book", "book", book).subscribe(new Consumer<Acknowledged>() {
            @Override
            public void accept(Acknowledged acknowledged) throws Exception {
                System.out.println(acknowledged);
            }
        });
    }
           

文檔的照例從RetrofitProxyServiceHolder這個單例類中擷取文檔操作相關的DocumentService代理對象,調用postDocument方法即可。三個參數分别對應索引,文檔類型與具體文檔。

3.2 批量文檔的索引

@Test
    public void batchPostDocumentTest() {
        BulkItem bulkItem1 = new BulkItem.Builder().operation(BulkOperationConstants.Operation.CREATE).document(new Music("Taylor swift", "Style"))
                .documentId("3").index("media").type(BulkOperationConstants.Type.CONCAT).build();

        BulkItem bulkItem2 = new BulkItem.Builder().operation(BulkOperationConstants.Operation.CREATE).document(new Music("Taylor swift", "Love Story"))
                .documentId("4").index("media").type(BulkOperationConstants.Type.CONCAT).build();

        RequestBody requestBody = new Bulk.Builder().item(bulkItem1).item(bulkItem2).build();

        DocumentService documentService = RetrofitProxyServiceHolder.getInstance().getDocumentServiceProxy();
        documentService.batchPostDocument(requestBody).subscribe(new Consumer<JsonObject>() {
            public void accept(JsonObject bulkResult) throws Exception {
                System.out.println(bulkResult);
            }
        });
    }
           

每個文檔對應一個BulkItem,建立好所有的BulkItem後傳入Bulk的構造器類,注意build方法的傳回結果為一個RequestBody,之後調用DocumentService接口的batchPostDocument方法即可完成多文檔的索引。

當然你也可以直接使用檔案建立RequestBody,檔案内容的格式需要遵循elk批量索引的文法:

4 查詢

smart-elk-client支援幾乎所有類型的查詢,包括詞條查詢,match查詢,模糊查詢,辨別符查詢,lucene文法查詢,範圍查詢,正則查詢,通配符查詢以及複合查詢(布爾查詢與權重查詢)。支援對查詢結果進行過濾與排序,高亮顯示。

下面是一個match查詢的示例:

@Test
    public void matchQueryTest() {
        QueryService queryService = RetrofitProxyServiceHolder.getInstance().getQueryServiceProxy();

        MatchQuery.Builder matchQueryBuilder = new MatchQuery.Builder();
        MatchQuery matchQuery = matchQueryBuilder.field("title").query("冰與火之歌").analyzer("ik_max_word").build();

        QueryBody.Builder queryBodyBuilder = new QueryBody.Builder();
        QueryBody queryBody = QueryBody queryBody = queryBodyBuilder.from(0).size(10).query(matchQuery.getQuery()).build();
        
        queryService.search("book", "book", queryBody.getQueryBody(), Book.class).subscribeOn(Schedulers.io()).subscribe(new Consumer<QueryResponse>() {
            @Override
            public void accept(QueryResponse queryResponse) throws Exception {
                System.out.println(queryResponse.getResults());
            }
        });
    }
           

所有查詢都需要先建構Query主體,每種類型的查詢的建構類具有不同的操作符,可以參照elk的rest api和構造器源碼(所有查詢構造器都位于com.tinysakura.core.query包下)使用。

Query主體建構完畢後建構通用的QueryBody,這裡可以指定一些查詢屬性、定義過濾器、定義排序條件等。同樣可以參照elk的rest api和項目源碼使用。

QueryBody建構完畢後傳入queryService的search方法即可,四個參數分别對應索引,文檔類型(非必須),queryBody和查詢文檔結果對應的java bean類型。反序列的結果存放在QueryResponse的results屬性下。由于使用了rxjava,可以靈活的使用操作符進行結果流操作和線程切換操作。

others

  1. 注意你的elk版本,不同的elk版本由于rest端點的不同可能導緻部分功能異常,本項目基于elastic serach 5.6版本開發。
  2. 用戶端支援多節點的elk,但配置時推薦将查詢主節點和響應性高的節點配置在非主節點和低響應性的節點之前,這樣可以提高部分性能。
  3. 項目源碼,歡迎大家的star。

繼續閱讀