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()); }

相关文章
相关标签/搜索