编写不易,转载请注明: (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