Elasticsearch學習(5)—— Java API

Elasticsearch Java API 

https://blog.csdn.net/wanbf123/article/details/78088444node

ES提供了多種語言(包括Java、Python、PHP、Ruby等)版本的Client API,能夠使用這些Client API編程實現數據操做功能。apache

使用Java API須要依賴ES所提供的jar包,咱們使用maven來下載所需的依賴包,maven依賴定義以下:編程

<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>1.5.0</version>
</dependency>json

version表示依賴包的版本,能夠輸入任意存在的版本,本文的示例中使用1.5.0版的API。注意,建議API的版本與ES集羣所使用的版本保持一致,以避免出現因版本不一致而致使的衝突。app

1. Client

ES中全部的Java API調用都要使用Client對象,ES爲API調用者提供了兩類Client對象:NodeClient和TransportClient。下面來說講這兩類Client的差別和使用場景。elasticsearch

1.1 NodeClient

NodeClient是一種嵌入式節點客戶端。它首先在客戶端啓動一個節點(Node),並加入同名集羣內。這個節點能夠保存數據,而且數據可以被索引。而後從這個節點中獲取Client,這類Client就是NodeClient。NodeClient無需指明ES服務端的地址,操做的數據位於啓動的節點所在的集羣中maven

得到NodeClient的代碼以下所示:工具

import org.elasticsearch.client.Client;
import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.node.Node;
import static org.elasticsearch.node.NodeBuilder.nodeBuilder;
 
public class MyNodeClient {
 
    public static void main(String[] args) {
        // 啓動一個本地節點,並加入子網內的ES集羣
        Node node = nodeBuilder()
                    .clusterName("elasticsearch") // 要加入的集羣名爲elasticsearch
                    // .client(true) //若是設置爲true,則該節點不會保存數據
                    .data(true) // 本嵌入式節點能夠保存數據
                    .node(); // 構建並啓動本節點
 
        // 得到一個Client對象,該對象能夠對子網內的「elasticsearch」集羣進行相關操做。
        Client nodeClient = node.client();
    }
}測試

運行這段代碼以後,能夠看到工程中新增了一個data文件夾,這是由於data(true)將Node設置爲能夠存放數據的節點,數據正是放在了data文件夾下ui

 

NodeClient適合用做單元或集成測試,而不適合用於生產環境。

1.2 TransportClient

TransportClient鏈接遠端的ES集羣,其自己並不會加入集羣

import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.transport.TransportAddress;
 
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
 
public class MyTransportClient {
 
    public static void main(String[] args) {
        // 配置信息
        Settings esSetting = settingsBuilder()
                                .put("cluster.name", "elasticsearch")
                                .build();
        TransportClient transportClient = new TransportClient(esSetting);
 
        // 添加鏈接地址
        TransportAddress address = new InetSocketTransportAddress("192.168.1.110", 9300);
        TransportAddress address2 = new InetSocketTransportAddress("192.168.1.111", 9300);
        transportClient.addTransportAddress(address);
        transportClient.addTransportAddress(address2);
    }
}

TransportClient適合用於生產環境中。

2. Index操做

2.1 建立索引

下面的方法建立一個索引,並同時建立一個mapping。mapping能夠傳入符合格式要求的json字符串。通常狀況下,咱們能夠使用下面的方式來生成所需的json字符串。

  1. 手動拼接json字符串
  2. 使用相似jackson的工具將對象轉換爲相應的json字符串
  3. 使用ES內置的XContentFactory.jsonBuilder()來建立json字符串。

/**
 * 建立一個索引
 * @param indexName 索引名
 */
public void createIndex(String indexName) {
    try {
        CreateIndexResponse indexResponse = this.client
                                .admin()
                                .indices()
                                .prepareCreate(indexName)
                                .get();
 
        System.out.println(indexResponse.isAcknowledged()); // true表示建立成功
    } catch (ElasticsearchException e) {
        e.printStackTrace();
    }
}

 若是須要在索引上新建mapping,可經過下面的代碼來實現。

/**
 * 給索引增長mapping。
 * @param index 索引名
 * @param type mapping所對應的type
 */
public void addMapping(String index, String type) {
    try {
        // 使用XContentBuilder建立Mapping
        XContentBuilder builder = 
            XContentFactory.jsonBuilder()
                            .startObject()
                                .field("properties")
                                    .startObject()
                                        .field("name")
                                            .startObject()
                                                .field("index", "not_analyzed")
                                                .field("type", "string")
                                            .endObject()
                                        .field("age")
                                            .startObject()
                                                .field("index", "not_analyzed")
                                                .field("type", "integer")
                                            .endObject()
                                    .endObject()
                            .endObject();
        System.out.println(builder.string());           
        PutMappingRequest mappingRequest =                     Requests.putMappingRequest(index).source(builder).type(type);
        this.client.admin().indices().putMapping(mappingRequest).actionGet();
    } catch (ElasticsearchException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

2.2 刪除索引 

/**
 * 刪除索引
 * @param index 要刪除的索引名
 */
public void deleteIndex(String index) {
    DeleteIndexResponse deleteIndexResponse = 
        this.client
            .admin()
            .indices()
            .prepareDelete(index)
            .get();
    System.out.println(deleteIndexResponse.isAcknowledged()); // true表示成功
}

3. 文檔CURD操做 

增刪改查是數據的基本操做,同時也是使用頻率最高的一類操做。本小節介紹使用Java API來實現document的增刪改查。

3.1 新增文檔

/**
 * 建立一個文檔
 * @param index index
 * @param type type
 */
public void createDoc(String index, String type) {
 
    try {
        // 使用XContentBuilder建立一個doc source
        XContentBuilder builder = 
            XContentFactory.jsonBuilder()
                            .startObject()
                                .field("name", "zhangsan")
                                .field("age", "lisi")
                            .endObject();
 
        IndexResponse indexResponse = this.client
                                        .prepareIndex()
                                        .setIndex(index)
                                        .setType(type)
                                        // .setId(id) // 若是沒有設置id,則ES會自動生成一個id
                                        .setSource(builder.string())
                                        .get();
        System.out.println(indexResponse.isCreated());
    } catch (ElasticsearchException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

3.2 更新文檔

/**
 * 更新文檔
 * @param index
 * @param type
 * @param id
 */
public void updateDoc(String index, String type, String id) {
    try {
        XContentBuilder builder = 
            XContentFactory.jsonBuilder()
                            .startObject()
                                .field("name", "lisi")
                                .field("age", 12)
                            .endObject();
 
        UpdateResponse updateResponse = 
            this.client
                .prepareUpdate()
                .setIndex(index)
                .setType(type)
                .setId(id)
                .setDoc(builder.string())
                .get();
        System.out.println(updateResponse.isCreated()); // true表示成功
    } catch (ElasticsearchException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

【注意】id參數必須是肯定存在的id值,不然會拋出document missing的異常。

3.3 查詢文檔

查詢文檔能夠是根據id查詢,也能夠是根據複雜的查詢條件查詢。根據id的get查詢代碼以下。

/**
 * 根據ID查詢一條數據記錄。
 * @param id 要查詢數據的ID。
 * @return 返回查詢出來的記錄對象的json字符串。
 */
public String get(String index, String type, String id) {
    GetResponse getResponse = this.client
                                .prepareGet()   // 準備進行get操做,此時還有真正地執行get操做。(與直接get的區別)
                                .setIndex(index)  // 要查詢的
                                .setType(type)
                                .setId(id)
                                .get();
    return getResponse.getSourceAsString();
}

基於複雜查詢條件的示例代碼以下。

/**
 * 使用filter方式查詢數據。
 * @param index 數據所在的索引名
 * @param type 數據所在的type
 * @return 
 */
public List<String> queryByFilter(String index, String type) {
 
    // 查詢名爲zhangsan的數據
    FilterBuilder filterBuilder = FilterBuilders.termFilter("name", "zhangsan");
    SearchResponse searchResponse = 
        this.client
            .prepareSearch()  
            .setIndices(index)
            .setTypes(type)
            .setPostFilter(filterBuilder)
            .get();
 
    List<String> docList = new ArrayList<String>();
    SearchHits searchHits = searchResponse.getHits();
    for (SearchHit hit : searchHits) {
        docList.add(hit.getSourceAsString());
    }
    return docList;
}  

3.4 刪除文檔

下面的代碼刪除指定id的文檔。

 /**
 * 刪除一條數據
 * @param index
 * @param type
 * @param id
 */
public void deleteDoc(String index, String type, String id) {
    DeleteResponse deleteResponse  = this.client
            .prepareDelete()  
            .setIndex(index)
            .setType(type)
            .setId(id)
            .get();
    System.out.println(deleteResponse.isFound()); // true表示成功
}

根據複雜的查詢條件來刪除文檔。

/**
 * 根據查詢條件刪除文檔。
 */
public void deleteByQuery(String index, String type) {
    try {
        QueryBuilder queryBuilder = QueryBuilders.termQuery("name", "zhangsan");
        DeleteByQueryResponse deleteByQueryResponse = this.client
                .prepareDeleteByQuery(index)
                .setTypes(type)
                .setQuery(queryBuilder)
                .get();
    } catch (ElasticsearchException e) {
        e.printStackTrace();
    }

4. 聚合操做 

聚合操做的API稍微比較複雜一點,本文僅以min聚合的示例來講明聚合API的調用方式,其餘的聚合API調用步驟相似。

/**  * 使用min聚合查詢某個字段上最小的值。  * @param index  * @param type  */ public void min(String index, String type) {     SearchResponse response = this.client                             .prepareSearch(index)                             .addAggregation(AggregationBuilders.min("min").field("age"))                             .get();       InternalMin min = response.getAggregations().get("min");     System.out.println(min.getValue()); }

相關文章
相關標籤/搜索