今天我的CSDN警句:程序员之所以犯错误,不是因为他们不懂,而是因为他们自以为什么都懂。
永远保持无知。
最近接触了ElasticSearch,挺好用的一个搜索引擎,昨天刚开始写,结合ElasticSearch JAVA API写了一个简单的工具类,如果有用了请拿走。
首先需要把%ESHOME%/lib中的包全部导入到项目中。
工具类就两个。
EsFinder ,用来封装查询所需要的条件,保存查询属性的
/**
* 2016-8-31
* EsFinder.java * author:zhouzhupianbei
*/
package com.zz.util.es;
import java.util.ArrayList;
import java.util.List;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
/**
* Es 的查询封装类
*
* @author zhouzhupianbei
* @date 2016-8-31
*/
public class EsFinder {
/**
* 所有的查询条件集合
*/
private List<QueryBuilder> qbs = new ArrayList<QueryBuilder>();
/**
* 所有的查询类型集合
*/
private List<String> types = new ArrayList<String>();
/**
* 所有的索引集名称集合
*/
private List<String> indexNames = new ArrayList<String>();
public EsFinder() {
}
/**
* 添加一个索引集名称
*
* @author zhouzhupianbei
* @date 2016-8-31
* @param indexName
* @return
*/
public EsFinder addIndexName(String indexName) {
this.indexNames.add(indexName);
return this;
}
/**
* 添加一个查询类型
*
* @author zhouzhupianbei
* @date 2016-8-31
* @param type
*/
public EsFinder addType(String type) {
this.types.add(type);
return this;
}
/**
* 模糊查询,并且将字段分词
*
* @author zhouzhupianbei
* @date 2016-8-31
* @param text
* 查询字段
* @param fields
* 查询涉及到的字段
*/
public EsFinder pushMultiMatchQuery(String text, String... fields) {
QueryBuilder qb = QueryBuilders.multiMatchQuery(text, fields);
this.qbs.add(qb);
return this;
}
/**
* 条件查询,要求字段与值完全相同
*
* @author zhouzhupianbei
* @date 2016-8-31
* @param obj
* @param field
* 查询涉及到的字段
* @return
*/
public EsFinder pushTermQuery(Object obj, String field) {
QueryBuilder qb = QueryBuilders.termQuery(field, obj);
this.qbs.add(qb);
return this;
}
public EsFinder pushMatchPhraseQuery(Object obj, String field) {
QueryBuilder qb = QueryBuilders.matchPhraseQuery(field, obj);
this.qbs.add(qb);
return this;
}
public List<QueryBuilder> getQueryBuilder() {
return qbs;
}
public void setQueryBuilder(List<QueryBuilder> qbs) {
this.qbs = qbs;
}
public List<String> getTypes() {
return types;
}
public void setTypes(List<String> types) {
this.types = types;
}
public List<String> getIndexNames() {
return indexNames;
}
public void setIndexNames(List<String> indexNames) {
this.indexNames = indexNames;
}
}
EsHandle,这个类是真正用于与搜索引擎交互的,将搜索引擎中的增加/删除/查询功能封装到了该类中
package com.zz.util.es;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import org.elasticsearch.action.delete.DeleteRequestBuilder;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import com.google.gson.Gson;
import com.ymkj.vo.es.EsVo;
/**
* 与ElasticSearch交互的工具类
* @author zhouzhupianbei
*
* @param <T>
*/
public class EsHandle<T> {
private Client client;
private Class<T> tClass;// 实体类的Class对象
public EsHandle(String ipAddress, Class<T> tClass)
throws UnknownHostException {
this(ipAddress, 9300, tClass);
}
public EsHandle(String ipAddress, int port, Class<T> tClass)
throws UnknownHostException {
this.client = TransportClient
.builder()
.build()
.addTransportAddress(
new InetSocketTransportAddress(InetAddress
.getByName(ipAddress), port));
this.tClass = tClass;
}
/**
* 建立索引,索引建立好之后,会在elasticsearch-0.20.6\data\elasticsearch\nodes\0创建所以你看
*
* @param indexName
* 为索引库名,一个es集群中可以有多个索引库。 名称必须为小写
* @param indexType
* Type为索引类型,是用来区分同索引库下不同类型的数据的,一个索引库下可以有多个索引类型。
* @param jsondata
* json格式的数据集合
*
* @return
*/
public void createIndexResponse(String indexname, String type,
List<String> jsondata, String id) {
// 创建索引库 需要注意的是.setRefresh(true)这里一定要设置,否则第一次建立索引查找不到数据
IndexRequestBuilder requestBuilder = client.prepareIndex(indexname,
type).setRefresh(true);
for (int i = 0; i < jsondata.size(); i++) {
requestBuilder.setSource(jsondata.get(i)).execute().actionGet();
}
}
/**
* 创建索引
*
* @param client
* @param jsondata
* @return
*/
public IndexResponse createIndexResponse(String indexname, String type,
String jsondata, String id) {
IndexResponse response = client.prepareIndex(indexname, type, id)
.setSource(jsondata).execute().actionGet();
return response;
}
public void delDate(String indexname, String type, String id) {
DeleteRequestBuilder request = client
.prepareDelete(indexname, type, id);
request.execute();// 执行删除
}
public List<T> search(EsFinder finder, int pageNo, int pageSize) {
List<T> list = new ArrayList<T>();
// 写入索引集
String[] indexNames = new String[finder.getIndexNames().size()];
indexNames = finder.getIndexNames().toArray(indexNames);
SearchRequestBuilder request = client.prepareSearch(indexNames)
.setExplain(true);
BoolQueryBuilder bollQuery = QueryBuilders.boolQuery();
// 写入查询条件
for (QueryBuilder qb : finder.getQueryBuilder()) {
bollQuery.must(qb);
}
request.setQuery(bollQuery);
// 写入Types
String[] types = new String[finder.getTypes().size()];
types = finder.getTypes().toArray(types);
request.setTypes(types);
// 分页,pageNo从0开始
request.setFrom(pageNo * pageSize).setSize(pageSize);
SearchResponse searchResponse = request.execute().actionGet();
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHists = hits.getHits();
Gson gson = new Gson();
if (searchHists.length > 0) {
for (SearchHit hit : searchHists) {
System.out.println(hit.getSourceAsString());
T ev = gson.fromJson(hit.getSourceAsString(), this.tClass);
list.add(ev);// 将查询到的值封装起来
}
}
return list;
}
public static void main(String[] args) throws UnknownHostException {
EsHandle<EsVo> eh = new EsHandle<EsVo>("192.168.1.101", 9300,
EsVo.class);
// 测试查询
EsFinder finder = new EsFinder();
finder.addIndexName("jyoa_").addType("bulletin")
.pushMultiMatchQuery("测试", "title", "content")
.pushTermQuery(8, "company");
eh.search(finder, 0, 15);
// //添加了50条测试数据
// for (int i = 0; i < 50; i++) {
// EsVo vo = new EsVo(i + 5, "这是一条测试公告" + i, "这是一条测试公告" + i,
// TimeHandler.timeToString(new Date().getTime()), "bulletin",
// "bulletin", 8 + "");
// List<String> list = new ArrayList<String>();
// list.add(vo.toString());
// System.out.println(vo.getMark());
// eh.createIndexResponse("jyoa_", "bulletin", list, (i + 5) + "");
//
// }
}
}
EsVo 是个测试的时候使用的类,自己也可以定义或者使用项目中的某些实体类。
由于ES只接收JSON数据,所以需要将实体类转换为JSON数据才可使用,我用的是GSON。
/**
* 2016-8-30
* EsVo.java * author:zhouzhupianbei
*/
package com.zz.vo.es;
import com.google.gson.Gson;
/**
* 存储在查询系统的
*
* @author zhouzhupianbei
* @date 2016-8-30
*/
public class EsVo {
private int id;
private String title;
private String content;// 内容
private String updateDate;// 创建时间
private String url;
private String mark;
private String company;// 公司ID
public EsVo() {
}
public EsVo(int id, String title, String content, String updateDate,
String url, String mark, String company) {
super();
this.id = id;
this.title = title;
this.content = content;
this.updateDate = updateDate;
this.url = url;
this.mark = mark;
this.company = company;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getMark() {
return mark;
}
public void setMark(String mark) {
this.mark = mark;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getUpdateDate() {
return updateDate;
}
public void setUpdateDate(String updateDate) {
this.updateDate = updateDate;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
private static Gson gson = null;
public String toString() {
if (gson == null) {
gson = new Gson();
}
return gson.toJson(this, EsVo.class);
}
}
以上代码均个人观点,并非权威。