Elasticsearch JAVA API 学习

今天我的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);
	}
}


以上代码均个人观点,并非权威。

猜你喜欢

转载自blog.csdn.net/zhouzhupianbei/article/details/52404001