简介
该代码是以组件的形式写入,使用时在其他方法中注入 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