简介

  该代码是以组件的形式写入,使用时在其他方法中注入  ElasticSearchUtil 类进行使用,主要实现了动态的增删改查,分页模糊查询,以指定字段查询与全部字段进行全差

should和must的比较

should模式:就算有一个字段没有匹配的也会有结果返回
must模式:必须要求所有字段都匹配到,只要有一个字段不匹配就没有搜索结果

版本信息

  • Elasticsearch:2.x
  • jdk  1.8

maven 依赖

<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.8.RELEASE</version>
	</parent>


	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<!-- elasticsearch start -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
		</dependency>
		<!-- springBoot start -->

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>com.sun.jna</groupId>
			<artifactId>jna</artifactId>
			<version>3.0.9</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jetty</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- springBoot end -->

		<!-- json start -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.4</version>
		</dependency>
		<!-- json end -->

	</dependencies>

config 底层操作类

package *.config;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.elasticsearch.action.bulk.BackoffPolicy;
import org.elasticsearch.action.bulk.BulkProcessor;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.unit.ByteSizeUnit;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
 * 底层操作类
 * @ClassName: ElasticConfigration 
 * @date 2018年11月20日
 * @author tang wang
 *
 */
@Component
public class ElasticConfigration {

	private final Logger logger = LoggerFactory.getLogger(ElasticConfigration.class);

	@Autowired
	private Client client;

	private BulkProcessor bulkProcessor;
	@PostConstruct
	public void initBulkProcessor() {

		bulkProcessor = BulkProcessor.builder(client, new BulkProcessor.Listener() {

			@Override
			public void beforeBulk(long executionId, BulkRequest request) {
				logger.info("序号:{} 开始执行{} 条记录保存", executionId, request.numberOfActions());
			}

			@Override
			public void afterBulk(long executionId, BulkRequest request, Throwable failure) {
				logger.error(String.format("序号:%s 执行失败; 总记录数:%s", executionId, request.numberOfActions()), failure);
			}

			@Override
			public void afterBulk(long executionId, BulkRequest request, BulkResponse response) {
				logger.info("序号:{} 执行{}条记录保存成功,耗时:{}毫秒,", executionId,
						request.numberOfActions(), response.getTookInMillis());
			}
		}).setBulkActions(1000)
				.setBulkSize(new ByteSizeValue(10, ByteSizeUnit.MB))
				.setConcurrentRequests(4)
				.setFlushInterval(TimeValue.timeValueSeconds(5))
				/**
				 * 失败后等待多久及重试次数
				 */
				.setBackoffPolicy(BackoffPolicy.exponentialBackoff(TimeValue.timeValueMillis(500), 3))  
				.build();
	}


	@PreDestroy
	public void closeBulk() {
		if (bulkProcessor != null) {
			try {
				bulkProcessor.close();
			} catch (Exception e) {
				logger.error("close bulkProcessor exception", e);
			}
		}
	}


	/**
	 * 批量添加,性能最好
	 * 
	 */
	public void addDocumentToBulkProcessor(String indices, String type, Object object) {
		bulkProcessor.add(client.prepareIndex(indices, type).setSource(JSONObject.toJSONString(object)).request());
	}

	/**
	 * 添加数据 
	 * @Title:  ElasticConfigration   
	 * @Description:
	 * @param indices 索引名字 
	 * @param type    索引类型
	 * @param object  索引数据
	 * @author: tao wang 
	 * @date:   2018年11月14日
	 * @throws
	 */
	public void addDocument(String indices, String type, Object object) {

		IndexResponse resp = client.prepareIndex(indices, type).setSource(JSONObject.toJSONString(object)).get();
		logger.info("添加结果:{}", resp.toString());
	}

	/**
	 * 按照Id 进行删除
	 * @Title:  ElasticConfigration   
	 * @Description:
	 * @param index  索引名称
	 * @param type   索引类型
	 * @param id     数据Id
	 * @author: tao wang 
	 * @date:   2018年11月14日
	 * @throws
	 */
	public void deleteDocumentById(String index, String type, String id) {
		// new DeleteByQueryRequest(search);
		DeleteResponse resp = client.prepareDelete(index, type, id).get();
		logger.info("删除结果:{}", resp.toString());
	}

	/**
	 * 查询单个数据
	 * @param  index 引擎名称
	 * @param  type  引擎类型
	 * @param  id    引擎Id  
	 * @return   
	 * @auth tao wang
	 */

	public JSONObject getDocmentById(String index, String type, String id) {
		JSONObject obj = new JSONObject();
		GetResponse getResponse = client.prepareGet(index, type, id).get();
		Map<String, Object> map = getResponse.getSource();
		obj.put("id", id);
		obj.put("value", map);
		return JSONObject.parseObject(JSONObject.toJSONString(map));
	}


	/**
	 * 按ID更新
	 * @Title:  ElasticConfigration   
	 * @Description:
	 * @param indices  索引名称
	 * @param type    索引类型
	 * @param id      数据Id
	 * @param object  数据值
	 * @author: tao wang 
	 * @date:   2018年11月14日
	 * @throws
	 */
	public void updateDocument(String indices, String type, String id, Object object) {
		UpdateResponse resp = client.prepareUpdate(indices, type, id).setDoc(JSONObject.toJSONString(object)).get();
		logger.info("更新结果:{}", resp.toString());
	}

	/**
	 * 查询所有字段,默认分页
	 * @Title:  ElasticConfigration   
	 * @Description:
	 * @param indices 索引名称
	 * @param type    索引类型
	 * @param clazz   返回的集合对象
	 * @return
	 * @author: tao wang 
	 * @date:   2018年11月14日
	 * @throws
	 */
	public JSONArray queryDocumentByParam(String indices, String type) {
		SearchRequestBuilder builder = buildRequest(indices, type);
		SearchResponse resp = builder.get();
		return convertResponse(resp);
	}

	/**
	 * 进行分页数据查询
	 * @param indices  索引名称
	 * @param type    索引类型
	 * @param key     模糊字段
	 * @param value   模糊字段
	 * @param pageNumber  当前页数
	 * @param pageSize    每页显示数据
	 * @return   
	 * @auth tao wang
	 * @date 2018年11月26日
	 */
	public JSONArray queryDocumentByParam(String indices, String type, String key, String value, Integer pageNumber, Integer pageSize) {
		SearchRequestBuilder builder = buildRequest(indices, type);
		BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
		/**
		 * must 满足所有才返回
		 */
		boolQueryBuilder.must(QueryBuilders.wildcardQuery(key, ("*" + value + "*").toLowerCase()));
		builder.setQuery(boolQueryBuilder);
		builder.setFrom(pageNumber).setSize(pageSize);
		SearchResponse resp = builder.get();
		return convertResponse(resp);
	}

	/**
	 * 进行模糊查询所有,不进行分页
	 * @param indices  索引名称
	 * @param type    索引类型
	 * @param value   模糊字段
	 * @param obj     类
	 * @return   
	 * @auth tao wang
	 * @date 2018年11月26日
	 */
	@SuppressWarnings("rawtypes")
	public JSONArray queryDocumentByParam(String indices, String type, String value, Class clazz) {

		SearchRequestBuilder builder = buildRequest(indices, type);
		BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();


		// 获取实体类的所有属性信息,返回Field数组  
		Field[] fields = clazz.getDeclaredFields();  
		System.err.println(fields.toString());
		for (Field field : fields) {  
			/**
			 * should 满足一个都返回
			 */
			boolQueryBuilder.should(QueryBuilders.wildcardQuery(field.getName(), ("*" + value + "*").toLowerCase()));
			System.err.println(field.getName());  
		}  			
		builder.setQuery(boolQueryBuilder);
		SearchResponse resp = builder.get();
		return convertResponse(resp);
	}

	/**
	 * 进行模糊查询所有,不进行分页
	 * @param indices  索引名称
	 * @param type    索引类型
	 * @param value   模糊字段
	 * @param setKey     类的属性名称
	 * @return   
	 * @auth tao wang
	 * @date 2018年11月26日
	 */
	public JSONArray queryDocumentByParam(String indices, String type, String value, Set<String> setKey) {

		SearchRequestBuilder builder = buildRequest(indices, type);
		BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
		for (String string : setKey) {
			boolQueryBuilder.should(QueryBuilders.wildcardQuery(string, ("*" + value + "*").toLowerCase()));	
		}
		builder.setQuery(boolQueryBuilder);
		SearchResponse resp = builder.get();
		return convertResponse(resp);
	}

	/**
	 * 通用的装换返回结果
	 * @Title:  ElasticConfigration   
	 * @Description:
	 * @param response 数据
	 * @param clazz    实体类
	 * @return
	 * @author: tao wang 
	 * @date:   2018年11月14日
	 * @throws
	 */
	public JSONArray convertResponse(SearchResponse response) {
		JSONArray list = new JSONArray();
		if (response != null && response.getHits() != null) {
			for (SearchHit hit : response.getHits()) {
				Map<String, Object> source = hit.getSource();
				String result = JSONObject.toJSONString(source);
				if (org.springframework.util.StringUtils.hasText(result)) {
					JSONObject obj = new JSONObject();
					obj.put("id", hit.getId());
					obj.put("value", result);
					list.add(obj);
				}
			}
		}
		return list;
	}

	/**
	 * 进行数据数据绑定
	 * @Title:  ElasticConfigration   
	 * @Description: 
	 * @param indices  索引名称
	 * @param type    索引类型
	 * @return
	 * @author: tao wang 
	 * @date:   2018年11月14日
	 * @throws
	 */
	public SearchRequestBuilder buildRequest(String indices, String type) {
		return client.prepareSearch(indices).setTypes(type);
	}
}

业务实现类: 

package *.util;

import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import *.config.ElasticConfigration;

/**
 * 业务实现接口
 * @ClassName: ElasticSearchUtil 
 * @date 2018年11月20日
 * @author tang wang
 *
 */
@Component
public class ElasticSearchUtil {

	@Autowired
	private  ElasticConfigration elasticConfigration;

	/**
	 * 添加指定的索引名称和类型数据
	 * @Title:  ElasticConfigUtil   
	 * @Description:
	 * @param indices 索引名称
	 * @param type    索引类型
	 * @param object  JSON 对象
	 * @return
	 * @author: tao wang 
	 * @date:   2018年11月14日
	 * @throws
	 */
	public  boolean   insert(String indices, String type, JSONObject object) {
		elasticConfigration.addDocument(indices.toLowerCase(), type.toLowerCase(), object);
		return true;
	}

	/**
	 * 添加多条数据
	 * @param indices 索引名称
	 * @param type    索引类型
	 * @param array   索引的对象集合
	 * @return
	 */
	public  boolean  insert(String indices, String type, JSONArray array) {
		for (Object object : array) {
			elasticConfigration.addDocument(indices.toLowerCase(), type.toLowerCase(), object);
		}
		return true;
	}

	/**
	 * 删除单条数据
	 * @param @param indices 索引名称
	 * @param @param type   索引类型
	 * @param @param id    索引Id
	 * @param @return 
	 * @return   
	 * @auth tao wang
	 */
	public boolean delete(String indices, String type, String id) {
		elasticConfigration.deleteDocumentById(indices.toLowerCase(), type.toLowerCase(), id);
		return true;
	}

	/**
	 * 删除多条数据
	 * @param @param indices 索引名称
	 * @param @param type    索引类型
	 * @param @param ids     id 集合
	 * @param @return 
	 * @return   
	 * @auth tao wang
	 */
	public boolean delete(String indices, String type, Set<String> ids) {
		for (String id : ids) {
			elasticConfigration.deleteDocumentById(indices.toLowerCase(), type.toLowerCase(), id);
		}
		return true;
	}

	/**
	 * 获取单个数据
	 * @param @param index 索引名称
	 * @param @param type 索引类型
	 * @param @param id   索引Id
	 * @param @return  返回数据
	 * @return   
	 * @auth tao wang
	 */
	public JSONObject getDocmentById(String indices, String type, String id) {
		return elasticConfigration.getDocmentById(indices.toLowerCase(), type.toLowerCase(), id);
	}

	/**
	 * 修改单条数据
	 * @param @param indices 索引名称
	 * @param @param type   索引类型
	 * @param @param id     索引Id
	 * @param @param object  修改数据 数据不修改传原值
	 * @param @return 
	 * @return   
	 * @auth tao wang
	 */
	public boolean  update(String indices, String type, String id, JSONObject object) {
		elasticConfigration.updateDocument(indices.toLowerCase(), type.toLowerCase(), id, object);
		return true;
	}

	/**
	 * 分页查询搜索引擎里面的数据
	 * @Title:  ElasticSearchUtil   
	 * @Description:
	 * @param pageNumber 当前页数
	 * @param pageSize  每页条数
	 * @param key    要模糊字段名称
	 * @param value  要模糊字段值
	 * @param indices 索引名称
	 * @param type    索引类型
	 * @param 
	 * @return
	 * @author: tao wang 
	 * @date:   2018年11月12日
	 * @throws
	 */

	public JSONArray searchEmployee(String indices, String type, Integer pageNumber, 
			Integer pageSize, String key, String value) {
		return elasticConfigration.queryDocumentByParam(indices.toLowerCase(), type.toLowerCase(),
				key, value, pageNumber, pageSize);
	}


	/**
	 * 查询搜索里面的数据
	 * @param indices 索引名称
	 * @param type   索引类型
	 * @param value  模糊字段名称
	 * @param obj    类属性
	 * @return   
	 * @auth tao wang
	 * @date 2018年11月26日
	 */
	@SuppressWarnings("rawtypes")
	public JSONArray searchEmployee(String indices, String type, String value, Class  clazz) {
		return elasticConfigration.queryDocumentByParam(indices.toLowerCase(), type.toLowerCase(), value, clazz);
	}

	/**
	 * 查询搜索里面的数据
	 * @param indices  索引名称
	 * @param type    索引类型
	 * @param value   模糊字段名称
	 * @param setKsy  类属性名称集合
	 * @return   
	 * @auth tao wang
	 * @date 2018年11月26日
	 */
	public JSONArray searchEmployee(String indices, String type, String value, Set<String> setKsy) {
		return elasticConfigration.queryDocumentByParam(indices.toLowerCase(), type.toLowerCase(), value, setKsy);
	}


	/**
	 * 不进行分页查询
	 * @Title:  ElasticSearchUtil   
	 * @Description:
	 * @param key    要模糊字段名称,多个中间逗号分开
	 * @param value  要模糊字段值
	 * @param indices 索引名称
	 * @param type    索引类型
	 * @param clazz   要返回的类集合
	 * @return
	 * @author: tao wang 
	 * @date:   2018年11月12日
	 * @throws
	 */

	public JSONArray searchEmployee(String indices, String type) {
		return elasticConfigration.queryDocumentByParam(indices.toLowerCase(), type.toLowerCase());
	}

}

配置类:application.properties

##es的名称 默认为elasticsearch
spring.data.elasticsearch.cluster-name=*
#配置es节点信息,逗号分隔,如果没有指定,则启动ClientNode
spring.data.elasticsearch.cluster-nodes=*:9300