ElasticSearch—— Java API

努力的碼農發表於2018-11-22

實戰

在瞭解了ES的基礎知識後,接下來就是實際操作了。

安裝

環境準備:
jdk 1.8
ElasticSearch 6.4.0
window7

步驟:

  1. 將下載下來的elasticsearch-6.4.0.zip 解壓
  2. 進入/bin目錄,直接在terminal視窗中執行elasticsearch.bat 命令,然後就可以看到如下啟動頁面;

ElasticSearch—— Java API
此時在瀏覽器中訪問http://localhost:9200 ;

在啟動過程中預設的jvm記憶體引數設定比較大,可以在config目錄下面的jvm.options中將-Xms和-Xmx調小

ElasticSearch—— Java API
至此表示單機版的ES已經成功啟動。

  1. 安裝head外掛(用來檢視ES叢集中的資料和健康資訊)
git clone git://github.com/mobz/elasticsearch-head.git
cd elasticsearch-head
npm install
npm run start
複製程式碼

啟動後,可以在瀏覽器中訪問9100埠

ElasticSearch—— Java API
至此headr安裝成功,可以在頁面上檢視整個叢集的資訊。

通過上述的幾個步驟,我們就成功的搭建了一個可以試驗的ES環境,使用header外掛可以更加方便的檢視ES中索引,分片和文件的資訊。

由於存在跨域問題,所以需要在elasticsearch目錄中config下的elasticsearch.yml檔案中新增

http.cors.enabled: true
http.cors.allow-origin: "*"
複製程式碼

Java 客戶端

ES是基於http和json來和客戶端互動的,因此官方也提供了一個RESTClient客戶端,所以我們也藉助這個client來實現增刪改查的操作。

依賴:

org.elasticsearch:elasticsearch:5.4.2 ->ES 平臺版本
org.elasticsearch.client:rest:5.4.2 -> restClient 版本
io.searchbox:jest:5.3.3 -> 基於RestClient的一個封裝

複製程式碼
  1. 初始化Client

在使用jest時,會建立一個全域性單例的JestClient,然後在整個應用的生命週期中都會使用該client

JestClientFactory factory = new JestClientFactory();
List<String> urls = new ArrayList<>();
//        urls.add("http://10.37.2.142:9900");
urls.add("http://127.0.0.1:9200");
//        urls.add("http://10.37.2.144:9900");
factory.setHttpClientConfig(new HttpClientConfig
                .Builder(urls)//叢集中所有的節點地址
                .multiThreaded(true)//是否使用多執行緒
                .defaultMaxTotalConnectionPerRoute(2)//每個路由最大連線數
                .maxTotalConnection(20)//整個應用最大的連線數
                .readTimeout(30000)//超時時間
                        .build());
JestClient client = factory.getObject();
複製程式碼

在應用中可以通過spring對client進行管理,在應用關閉時需要呼叫client.shutdownClient();將資源進行釋放

  1. 建立index
Settings.Builder settingsBuilder = Settings.builder();
settingsBuilder.put("number_of_shards",5);//主分片數
settingsBuilder.put("number_of_replicas",1);//副本數

jestClient.execute(new CreateIndex.Builder("index").settings(settingsBuilder.build().getAsMap()).build());

//建立對映-mapping
PutMapping putMapping = new PutMapping.Builder(
        "my_index",
        "my_type",
        "{ \"my_type\" : { \"properties\" : { \"message\" : {\"type\" : \"string\", \"store\" : \"yes\"} } } }"
).build();
client.execute(putMapping);
複製程式碼

ES預設是允許動態建立的,所以在建立index時可以不用建立型別的mapping,然後儲存document時會動態的建立mapping,查詢index下所有型別的mapping

GET 127.0.0.1:9200/db1/_mapping

  1. 刪除index

    jestClient.execute(new DeleteIndex.Builder(index)
                    .build());
    複製程式碼
  2. 增加document

    document的增加是比較簡單的

    String source = "{\"user\":\"kimchy\"}";//使用接送字串
    String source = jsonBuilder()
                    .startObject()
                    .field("user", "kimchy")
                    .field("postDate", "date")
                    .field("message", "trying out Elastic Search")
                    .endObject().string();//使用構造的json
    Map<String, String> source = new LinkedHashMap<String,String>();//使用map
    source.put("user", "kimchy");
    Article source = new Article();//使用pojo物件
    source.setAuthor("John Ronald Reuel Tolkien");
    source.setContent("The Lord of the Rings is an epic high fantasy novel");
    
    Index index = new Index.Builder(source)
                            .index("twitter")//指定index
                            .type("tweet")//指定type
                            .id("1")//指定id,可以不指定則ES自動生成id
                            .build();
    jestClient.execute(index);
    複製程式碼

    以上是單個增加,我們同樣可以使用Bulk批量的插入ES:

    List<Index> indexList = new ArrayList<>();
    for (OrderDto t : datas) {
                Index indexDoc = new Index.Builder(t).index(index).type(type).build();
                indexList.add(indexDoc);
                Bulk.Builder bulkBuilder = new Bulk.Builder();
                bulkBuilder.addAction(indexList);
                BulkResult br = jestClient.execute(bulkBuilder.build());
    }
    
    複製程式碼
  3. 刪除document

每個document都是由index,type,id三者共同唯一確定的,所以可以指定刪除某個document:

jestClient.execute(new Delete.Builder("1")//id =1
        .index("index")//  index = index
        .type("type")// type = type
        .build());
複製程式碼

同樣的我們可以根據條件進行刪除:

String query ="\"{\n"+
                    "\"query\": {\n"+
                "\"match_all\": {}\n"+
            "}\"";//查詢條件
DeleteByQuery deleteByQuery = new DeleteByQuery.Builder(query).build();
JestResult deleteResult = jestClient.execute(deleteByQuery);
複製程式碼

如上,表示刪除所有的document,查詢的條件後面會介紹。

  1. 檢索

一切都是為了檢索
檢索才是ES的最誘人的特性,首先先簡單感受一下

    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    TermQueryBuilder memberTerm = QueryBuilders.termQuery("memberId", memberId);//等值查詢
    Integer[] channels = {101, 106};
    TermsQueryBuilder orderChannelTerm = QueryBuilders.termsQuery("orderChannel", channels);//in查詢
    Integer[] activeType = {0, 8, 9, 7};
    TermsQueryBuilder activeTypeTerm = QueryBuilders.termsQuery("activeType", activeType);
    AggregationBuilder orderItemIdAgg =    .field("b2corditemid").size(Integer.MAX_VALUE);
    Date now = new Date();
    Calendar calendar = Calendar.getInstance(); //得到日曆
    calendar.setTime(now);//把當前時間賦給日曆
    calendar.add(calendar.MONTH, -3); //設定為前3月
    Date dBefore = calendar.getTime(); //得到前3月的時間
    RangeQueryBuilder payTimeRange = QueryBuilders.rangeQuery("payTime").gt(dBefore).lt(now);//範圍查詢

    searchSourceBuilder.query(QueryBuilders.boolQuery()
        .must(memberTerm)// and查詢
        .filter(orderChannelTerm)//
        .filter(activeTypeTerm)
        .filter(payTimeRange)
        );
    Sort placeTimeSort = new Sort("placeTime", Sort.Sorting.DESC);
    Sort idSort = new Sort("orderId", Sort.Sorting.ASC);
    searchSourceBuilder.aggregation(orderItemIdAgg);// group by 分組
    searchSourceBuilder.from(0).size(20);
    Search search = new Search.Builder(searchSourceBuilder.toString())
                    .addType(type)
                    .addIndex(index)
                    .addSort(placeTimeSort)//結果排序
                    .addSort(idSort)
                    .build();
複製程式碼

如上的查詢可以類似於sql:

SELECT
	*
FROM
	bm_client_order_detail o
WHERE
	o.`payTime` >= DATE_SUB(NOW(), INTERVAL 3 MONTH)
AND o.memberId = 101204389
AND o.orderChannel IN (101, 106)
AND activeType IN (0, 8, 9, 17)
GROUP BY
	o.b2corditemid
ORDER BY
	o.placeTime DESC,
	o.id ASC
LIMIT 0,20
複製程式碼

重點回顧

  • 單機版ES的安裝
  • elasticsearch-header的安裝和使用
  • JestClient的使用
    1. 初始化
    2. index建立
    3. index刪除
    4. 增加document
    5. 刪除document
    6. 檢索document

未完待續!!!

相關文章