Jest:ElasticSearch Java Http Rest 客户端使用

 

编写不易,转载请注明: (http://shihlei.iteye.com/blog/2411470)

一 概述

Jest 是一个Java 版的ElasticSearch Http Rest 客户端,基于HttpClient 封装实现。

 

个人感觉好处:

1 连接池可控

2 简单封装了Bean 到Document 的Mapping过程

 

github:https://github.com/searchbox-io/Jest/tree/master/jest

 

二 环境

(1)版本信息

elasticsearch:elasticsearch-6.2.2.tar.gz

jest:5.3.3

 

(2)环境准备:

a)创建索引

curl -H 'Content-Type: application/json' -XPUT 'http://localhost:9200/indexdb' -d '{
    "settings" : {
        "index" : {
            "number_of_shards" : 1,
            "number_of_replicas" : 1
        }
    }
}'

 

b)创建mapping

curl  -H 'Content-Type: application/json' -XPUT 'http://localhost:9200/indexdb/_mapping/docs' -d '{
   "properties": {
      "id": {
            "type": "long",
            "index": "false"
       },
       "title": {
            "type": "keyword",
       },
       "author": {
            "type": "keyword",
       },
       "tags": {
            "type": "keyword",
            "boost" : 3.0,
       },
       "publishTime": {
            "type": "date",
            "format": "yyyy-MM-dd HH:mm:ss"
       }
   }
}'

    注:升级到6.2 mapping 取消string 类型,index 只接受true,false。

 

三 Demo

1)maven 依赖

<!--Java HTTP Rest client for ElasticSearch.-->
        <dependency>
            <groupId>io.searchbox</groupId>
            <artifactId>jest</artifactId>
            <version>5.3.3</version>
        </dependency>

 

2)Bean

package x.search.es.simple.bean;

import java.util.Arrays;
import java.util.Date;

import io.searchbox.annotations.JestId;

public class Document implements Cloneable {
    @JestId
    private long id;
    private String title;
    private String author;
    private String[] tags;
    private Date publishTime;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String[] getTags() {
        return tags;
    }

    public void setTags(String[] tags) {
        this.tags = tags;
    }

    public Date getPublishTime() {
        return publishTime;
    }

    public void setPublishTime(Date publishTime) {
        this.publishTime = publishTime;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    @Override
    public String toString() {
        return "Document{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", author='" + author + '\'' +
                ", tags=" + Arrays.toString(tags) +
                ", publishTime=" + publishTime +
                '}';
    }
}

 

3)JestClient 工厂

package x.search.es.simple.jest;

import java.util.Objects;

import com.google.gson.GsonBuilder;
import io.searchbox.client.JestClient;
import io.searchbox.client.JestClientFactory;
import io.searchbox.client.config.HttpClientConfig;

public class EsJestClient {

    private static final String ES_HOST = "http://127.0.0.1";
    private static final int ES_HTTP_PORT = 9200;

    private static JestClient client;

    /**
     * 获取客户端
     *
     * @return jestclient
     */
    public static synchronized JestClient getClient() {
        if (client == null) {
            build();
        }
        return client;
    }

    /**
     * 关闭客户端
     */
    public static void close(JestClient client) {
        if (!Objects.isNull(client)) {
            try {
                client.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 建立连接
     */
    private static void build() {
        JestClientFactory factory = new JestClientFactory();
        factory.setHttpClientConfig(
                new HttpClientConfig
                        .Builder(ES_HOST + ":" + ES_HTTP_PORT)
                        .multiThreaded(true)
                        //一个route 默认不超过2个连接  路由是指连接到某个远程注解的个数。总连接数=route个数 * defaultMaxTotalConnectionPerRoute
                        .defaultMaxTotalConnectionPerRoute(2)
                        //所有route连接总数
                        .maxTotalConnection(2)
                        .connTimeout(10000)
                        .readTimeout(10000)
                        .gson(new GsonBuilder()
                                .setDateFormat("yyyy-MM-dd HH:mm:ss")
                                .create())
                        .build()
        );
        client = factory.getObject();
    }
}

 

4)CRUD

 

(a)IDocumentDao

package x.search.es.simple;

import x.search.es.simple.bean.Document;

import java.util.List;

public interface IDocumentDao {
    /**
     * 插入
     *
     * @param doc
     * @return
     */
    boolean insert(Document doc);

    /**
     * 替换
     *
     * @param doc
     * @return
     */
    boolean replace(Document doc);

    /**
     * 更新
     *
     * @param doc
     * @return
     */
    boolean update(Document doc);


    /**
     * 删除
     *
     * @param id
     * @return
     */
    boolean delete(long id);

    /**
     * 根据ID查询
     *
     * @param id
     * @return
     */
    Document searchById(long id);

    /**
     * 条件查询
     *
     * @param criterias
     * @return
     */
    List<Document> search(List<Criteria> criterias);

    /**
     * 条件删除
     *
     * @param criterias
     * @return 删除的document数量
     */
    int deleteByQuery(List<Criteria> criterias);
}

 

(b)Criteria 

package x.search.es.simple;

public class Criteria {
    private String fieldName;
    private Object fieldValue;

    public Criteria(String fieldName, Object fieldValue) {
        this.fieldName = fieldName;
        this.fieldValue = fieldValue;
    }

    public String getFieldName() {
        return fieldName;
    }

    public Object getFieldValue() {
        return fieldValue;
    }
}

 (c)DocumentDB

package x.search.es.simple;

public class  DocumentDB {
    //indices 名必须小写
    public static final String INDICES = "indexdb";
    // type 名必须小写
    public static final String TYPE = "docs";
}

 

 (d)DocumentJestDaoImpl

package x.search.es.simple.jest;

import java.util.Date;
import java.util.List;

import io.searchbox.client.JestClient;
import io.searchbox.client.JestResult;
import io.searchbox.core.Delete;
import io.searchbox.core.DeleteByQuery;
import io.searchbox.core.DocumentResult;
import io.searchbox.core.Get;
import io.searchbox.core.Index;
import io.searchbox.core.Search;
import io.searchbox.core.SearchResult;
import io.searchbox.core.Update;
import io.searchbox.core.UpdateByQuery;
import io.searchbox.core.UpdateByQueryResult;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import x.search.es.simple.Criteria;
import x.search.es.simple.DocumentDB;
import x.search.es.simple.IDocumentDao;
import x.search.es.simple.bean.Document;

public class DocumentJestDaoImpl implements IDocumentDao {

    private JestClient client;

    private DocumentJestDaoImpl(JestClient client) {
        this.client = client;
    }

    public static void main(String[] args) {
        JestClient client = EsJestClient.getClient();
        DocumentJestDaoImpl documentDao = new DocumentJestDaoImpl(client);

        Document document = new Document();
        document.setId(1);
        document.setTitle("foo");
        document.setAuthor("bar");
        document.setPublishTime(new Date());
        document.setTags(new String[]{"tag1", "tag2", "tag3", "tag4"});

        //保存
        documentDao.insert(document);
        System.out.println(documentDao.searchById(1));
    }

    /**
     * 插入
     *
     * @param doc 文档
     * @return 是佛插入成功
     */
    @Override
    public boolean insert(Document doc) {
        try {
            DocumentResult result = client.execute(new Index.Builder(doc)
                    .index(DocumentDB.INDICES)
                    .type(DocumentDB.TYPE)
                    .refresh(true)
                    .build());
            return result.isSucceeded();
        } catch (Exception e) {
            throw new RuntimeException("insert exception", e);
        }
    }

    /**
     * 替换
     *
     * @param doc 文档
     * @return 是否执行成功
     */
    @Override
    public boolean replace(Document doc) {
        return update(doc);
    }

    /**
     * 更新
     *
     * @param doc 文档
     * @return 是否更新成功
     */
    @Override
    public boolean update(Document doc) {
        try {
            DocumentResult result = client.execute(new Update.Builder(doc)
                    .index(DocumentDB.INDICES)
                    .type(DocumentDB.TYPE)
                    .refresh(true)
                    .build());
            return result.isSucceeded();
        } catch (Exception e) {
            throw new RuntimeException("update exception", e);
        }
    }

    /**
     * 删除
     *
     * @param id 文档id
     * @return 是否执行成功
     */
    @Override
    public boolean delete(long id) {
        try {
            DocumentResult result = client.execute(new Delete.Builder(String.valueOf(id))
                    .index(DocumentDB.INDICES)
                    .type(DocumentDB.TYPE)
                    .build());
            return result.isSucceeded();
        } catch (Exception e) {
            throw new RuntimeException("delete exception", e);
        }
    }

    /**
     * 根据ID查询
     *
     * @param id id
     * @return 文档
     */
    @Override
    public Document searchById(long id) {
        try {
            DocumentResult result = client.execute(new Get.Builder(DocumentDB.INDICES, String.valueOf(id))
                    .type(DocumentDB.TYPE)
                    .build());
            return result.getSourceAsObject(Document.class);
        } catch (Exception e) {
            throw new RuntimeException("searchById exception", e);
        }
    }

    /**
     * 条件查询
     *
     * @param criterias 条件列表
     * @return 结果集
     */
    @Override
    public List<Document> search(List<Criteria> criterias) {
        try {
            SearchResult result = client.execute(new Search.Builder(buildSearch(criterias).toString())
                    // multiple index or types can be added.
                    .addIndex(DocumentDB.INDICES)
                    .addType(DocumentDB.TYPE)
                    .build());
            return result.getSourceAsObjectList(Document.class, false);

        } catch (Exception e) {
            throw new RuntimeException("search exception", e);
        }
    }

    private SearchSourceBuilder buildSearch(List<Criteria> criterias) {
        //指定查询的库表
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        if (criterias != null && !criterias.isEmpty()) {
            //构建查询条件必须嵌入filter中!
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            for (Criteria c : criterias) {
                boolQueryBuilder.filter(QueryBuilders.termQuery(c.getFieldName(), c.getFieldValue()));
            }

            searchSourceBuilder.query(boolQueryBuilder);
        }
        return searchSourceBuilder;
    }
    /**
     * 条件删除 ,ElasticSearch V5.1 以上可用
     *
     * @param criterias 条件
     * @return 删除的document数量
     */
    @Override
    public int deleteByQuery(List<Criteria> criterias) {
        try {
            JestResult result = client.execute(new DeleteByQuery.Builder(buildSearch(criterias).toString())
                    .addIndex(DocumentDB.INDICES)
                    .addType(DocumentDB.TYPE)
                    .build());

            return result.getJsonObject().get("deleted").getAsInt();
        } catch (Exception e) {
            throw new RuntimeException("deleteByQuery exception", e);
        }
    }
}

 

附录:

1)elasticsearch 6.2 安装

(1)下载解压

 

cd /opt/
curl -L -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.2.2.tar.gz
tar -xvf elasticsearch-6.2.2.tar.gz
 

 

(2)创建用户

 

groupadd es
useradd -r -g es -s /bin/bash es
chown -hR es:es /opt/elasticsearch-6.2.2
 

 

(3)启动

su es
cd /opt/elasticsearch-6.2.2/bin
./elasticsearch

 

猜你喜欢

转载自shihlei.iteye.com/blog/2411470