1.导入依懒:
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.4.3</version>
</dependency>
2.配置文件
spring:
data:
elasticsearch:
cluster-name: cluster-name
ip: 10.113.40.110,0.113.40.109,0.113.40.111,0.113.40.100
port: 9300
3.编写配置类
@Slf4j
@Component
public class ElasticConfig {
@Value("${spring.data.elasticsearch.ip}")
private String hostName; //es集群地址
@Value("${spring.data.elasticsearch.port}")
private Integer port; //es端口
@Value("${spring.data.elasticsearch.cluster-name}")
private String clusterName; //es集群名称
private Map<String, Integer> ipsAndPort = new HashMap<>();//保存集群地址和端口
@Bean
public TransportClient transportClient() {
log.info("ElasticSearch初始化开始...");
TransportClient client = null;
TransportAddress transportAddress = null;
try {
Settings esSetting = Settings.builder()
.put("cluster.name", clusterName) //集群名字
.put("client.transport.sniff", true)//增加嗅探机制,找到ES集群
.build();
client = new PreBuiltTransportClient(esSetting);
if (hostName.contains(",")) {
String[] split = hostName.split(",");
for (String ip : split) {
ipsAndPort.put(ip, port);
}
} else {
ipsAndPort.put(hostName, port);
}
for (Map.Entry<String, Integer> entry : ipsAndPort.entrySet()) {
transportAddress = new TransportAddress(InetAddress.getByName(entry.getKey()), Integer.valueOf(entry.getValue()));
client.addTransportAddress(transportAddress);
}
} catch (UnknownHostException e) {
log.error("错误信息", e);
}
return client;
}
}
4.工具使用类
@Slf4j
@Component
public class ElasticSearchUtil {
@Autowired
private TransportClient transportClient;
private static TransportClient client;
public static Object createIndexByByClass(String str, String indexSuffix, String typeSuffix) {
Object indexByJson = null;
try {
Class<?> aClass = Class.forName(str);
ESDTO esdto = autoCreateMapping(aClass);
if (esdto == null) {
return "自动创建mapping失败,请联系管理员!";
}
String indexName = esdto.getIndexName() + indexSuffix;
String type = esdto.getType() + typeSuffix;
Map<String, Map<String, String>> fieldsMap = esdto.getFieldsMap();
indexByJson = createIndexByJson(indexName, type, fieldsMap);
JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSON(indexByJson).toString());
if (jsonObject.getBoolean("acknowledged")) {
Map<String, Object> result = queryMappingInfo(indexName, type);
return result;
}
} catch (ClassNotFoundException e) {
return "自动创建mapping失败";
}
return indexByJson;
}
public static ESDTO autoCreateMapping(Class clazz) {
ESDTO esdto = new ESDTO();
Index annotation = (Index) clazz.getAnnotation(Index.class);
try {
if (annotation != null) {
String index = annotation.index();
String type = annotation.type();
esdto.setIndexName(index);
esdto.setType(type);
HashMap<String, Map<String, String>> properties = new HashMap<>();
Field[] fields = clazz.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
String name = fields[i].getName();
Fields fied = clazz.getDeclaredField(name).getAnnotation(Fields.class);
String fieldName = fied.fieldName();
String fieldType = fied.fieldType();
HashMap<String, String> fieldsMap = new HashMap<>();
fieldsMap.put("type", fieldType);
properties.put(fieldName, fieldsMap);
esdto.setFieldsMap(properties);
}
}
} catch (NoSuchFieldException e) {
log.info("反射创建mapping 失败!", e);
return null;
}
return esdto;
}
/**
* spring容器初始化的时候执行该方法
*/
@PostConstruct
public void init() {
client = this.transportClient;
}
/**
* 创建索引
*
* @param index
* @return
*/
public static boolean createIndex(String index, Integer shards) {
if (!isIndexExist(index)) {
log.info("Index is not exits!");
}
CreateIndexResponse indexresponse = client
.admin()
.indices()
.prepareCreate(index)
.setSettings(
Settings.builder()
.put("index.number_of_shards", shards)
.put("index.number_of_replicas", 1))
.execute()
.actionGet();
if (indexresponse.isAcknowledged()) {
log.info("索引执行建立成功!");
} else {
log.info("索引执行建立失败!");
}
return indexresponse.isAcknowledged();
}
/**
* 创建索引
* 根据静态mapping创建索引
*
* @param indexName
* @param type
* @param fieldsMap
* @return
*/
public static Object createIndexByJson(String indexName, String type, Map<String, Map<String, String>> fieldsMap) {
CreateIndexResponse response = null;
try {
//获取索引管理器
IndicesAdminClient indices = client.admin().indices();
boolean exists = indices.prepareExists(indexName).get().isExists();
//指定索引名称
CreateIndexRequestBuilder request = indices.prepareCreate(indexName);
if (exists) { //索引已存在,执行新增操作
return "索引已存在";
}
//获取构建静态mapping的builder
XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject("properties");
//将传入的静态mapping参数依次封装到mapping中
Set<String> fields = fieldsMap.keySet();
for (String field : fields) {
Map<String, String> fieldType = fieldsMap.get(field);
mapping.startObject(field);
for (Map.Entry<String, String> entry : fieldType.entrySet()) {
mapping.field(entry.getKey(), entry.getValue());
}
mapping.endObject();
}
//关闭json构造
mapping.endObject().endObject();
//添加mapping并创建索引
request.addMapping(type, mapping);
response = request.execute().actionGet();
} catch (IOException e) {
log.error("根据静态mapping创建索引 发生异常。。。。");
}
return response;
}
/**
* queryDataByType
*
* @param index
* @param type
* @return
*/
public static List<Map<String, Object>> queryDataAll(String index, String type) {
SearchResponse response = client.prepareSearch(index)
.setTypes(type)
.setQuery(QueryBuilders.matchAllQuery())
.setFrom(0)
.setSize(10)
.setExplain(true)//排序
.execute()
.actionGet();
SearchHits searchHits = response.getHits();
List<Map<String, Object>> list = new ArrayList<>();
for (int i = 0; i < searchHits.getHits().length; i++) {
list.add(searchHits.getAt(i).getSourceAsMap());
}
return list;
}
/**
* 查询mapping信息
*
* @param index
* @param type
* @return
*/
public static Map<String, Object> queryMappingInfo(String index, String type) {
ImmutableOpenMap<String, MappingMetaData> mappings = client.admin().cluster().prepareState().execute()
.actionGet().getState().getMetaData().getIndices().get(index).getMappings();
Map<String, Object> mapping = mappings.get(type).sourceAsMap();
return mapping;
}
/**
* 删除索引
*
* @param index
* @return
*/
public static boolean deleteIndex(String index) {
if (!isIndexExist(index)) {
log.info("Index is not exits!");
}
DeleteIndexResponse dResponse = client.admin().indices().prepareDelete(index).execute().actionGet();
if (dResponse.isAcknowledged()) {
log.info("delete index " + index + " successfully!");
} else {
log.info("Fail to delete index " + index);
}
return dResponse.isAcknowledged();
}
/**
* 数据添加
*
* @param jsonObject 要增加的数据
* @param index 索引,类似数据库
* @param type 类型,类似表
* @return
*/
public static String addData(JSONObject jsonObject, String index, String type) {
return addData(jsonObject, index, type, UUID.randomUUID().toString().replaceAll("-", "").toUpperCase());
}
/**
* 数据添加,返回ID
*
* @param jsonObject 要增加的数据
* @param index 索引,类似数据库
* @param type 类型,类似表
* @param id 数据ID
* @return
*/
public static String addData(JSONObject jsonObject, String index, String type, String id) {
IndexResponse response = client.prepareIndex(index, type, id).setSource(jsonObject).get();
log.info("addData response status:{},id:{}", response.status().getStatus(), response.getId());
return response.getId();
}
/**
* 批量添加数据
*
* @param list
* @param index
* @param type
* @param <T>
* @return
*/
public static <T> void addBatchData(List<T> list, String index, String type) {
BulkRequestBuilder builder = client.prepareBulk();
int count = 0;
long start = Instant.now().toEpochMilli();
if (CollectionUtils.isNotEmpty(list)) {
for (T t : list) {
JSONObject jsonObject = (JSONObject) JSONObject.toJSON(t);
builder.add(client.prepareIndex(index, type).setSource(jsonObject));
if (++count % 5000 == 0) {
builder.execute().actionGet();
builder = client.prepareBulk();
}
}
}
if (builder.numberOfActions() != 0) {
builder.execute().actionGet();
}
long end = Instant.now().toEpochMilli();
log.info("es数据同步完成,数据量:---> {} ,es插入耗时:---> {}ms", list.size(), (end - start));
}
/**
* 批量添加数据2
*
* @param list
* @param index
* @param type
* @param <T>
* @throws Exception
*/
public static <T> void addBatchData2(List<T> list, String index, String type) throws Exception {
BulkRequestBuilder builder = client.prepareBulk();
int count = 0;
long start = Instant.now().toEpochMilli();
if (CollectionUtils.isNotEmpty(list)) {
for (T t : list) {
String key = null;
Field[] declaredFields = t.getClass().getDeclaredFields();
for (int i = 0; i < declaredFields.length; i++) {
declaredFields[i].setAccessible(true);
String name = declaredFields[i].getName();
//PrimaryKey primaryKey = t.getClass().getDeclaredField(name).getAnnotation(PrimaryKey.class);
boolean present = t.getClass().getDeclaredField(name).isAnnotationPresent(PrimaryKey.class);
if (present == true) {
key = declaredFields[i].get(t).toString();
break;
}
}
if (null == key) {
throw new Exception("文档 primaryKey 不能为空!!!");
}
JSONObject jsonObject = (JSONObject) JSONObject.toJSON(t);
builder.add(client.prepareIndex(index, type, key).setSource(jsonObject));
if (++count % 5000 == 0) {
builder.execute().actionGet();
builder = client.prepareBulk();
}
}
}
if (builder.numberOfActions() != 0) {
printBlukLog(builder, "addBatchData2");
}
long end = Instant.now().toEpochMilli();
log.info("es数据同步完成,数据量:---> {} ,es插入耗时:---> {}ms", list.size(), (end - start));
}
/**
* 批量删除当前索引下的数据
*
* @param index
*/
public static long deleteBatchData(String index) {
long start = Instant.now().toEpochMilli();
BulkByScrollResponse response = DeleteByQueryAction.INSTANCE
.newRequestBuilder(client)
.filter(QueryBuilders.matchAllQuery())
.source(index)
.get();
long count = response.getDeleted();
long end = Instant.now().toEpochMilli();
log.info("{} 索引数据删除完成,数据总量:---> {} ,共耗时:---> {}ms", index, count, (end - start));
return count;
}
/**
* 指定字段,值删除文档
*
* @param index
* @param fieldName
* @param value
* @return
*/
public static long deleteByFieldAndValue(String index, String fieldName, Object value) {
if (StringUtils.isBlank(index) || StringUtils.isBlank(fieldName)) {
log.info("deleteByFieldAndValue fieldName is Blank");
return 0;
}
if (!isIndexExist(index)) {
log.error("Index is not exits!");
return 0;
}
long start = Instant.now().toEpochMilli();
BulkByScrollResponse response = DeleteByQueryAction.INSTANCE
.newRequestBuilder(client)
.filter(new TermQueryBuilder(fieldName, value))
.source(index)
.get();
long count = response.getDeleted();
long end = Instant.now().toEpochMilli();
log.info("{} 索引数据删除完成,数据总量:---> {} ,共耗时:---> {}ms", index, count, (end - start));
return count;
}
/**
* 批量更新当前索引下的数据
*
* @param index
*/
public static <T> long updateBatchData(List<T> list, String index, String term) {
long start = Instant.now().toEpochMilli();
UpdateByQueryRequestBuilder requestBuilder = UpdateByQueryAction.INSTANCE.newRequestBuilder(client);
for (T t : list) {
/** 目前批量更新只能手写
* new Script("ctx._source.goodsShow="+cartsSearchDTO.getGoodsShow()
* +";ctx._source.goodsPrice="+cartsSearchDTO.getGoodsPrice()
* +";ctx._source.goodsImages='"+cartsSearchDTO.getGoodsImages()
* +"';ctx._source.goodsState="+cartsSearchDTO.getGoodsState()
* +";ctx._source.oldGoodsPrice="+cartsSearchDTO.getOldGoodsPrice()
* +";ctx._source.goodsTransfeeCharge="+cartsSearchDTO.getGoodsTransfeeCharge()
* +";ctx._source.isIntereFree="+cartsSearchDTO.getIsIntereFree()
* +";ctx._source.goodsNowStorage="+cartsSearchDTO.getGoodsNowStorage()
* +";ctx._source.goodsName='"+cartsSearchDTO.getGoodsName()+"';"));
*/
requestBuilder.filter(QueryBuilders.termQuery(term, "")).source(index);
requestBuilder.script(new Script(t.toString()));
}
long count = requestBuilder.get().getUpdated();
long end = Instant.now().toEpochMilli();
log.info("{} 索引数据删除完成,数据总量:---> {} ,共耗时:---> {}ms", index, count, (end - start));
return count;
}
/**
* 聚合查询某个字段最大值
*
* @param index 索引,类似数据库
* @param type 类型,类似表
* @param
*/
public static int max(String index, String type, String column) {
//由于是聚合,这里使用的是AggregationBuilder。maxSecond是自己定义的给查询出来的最大值起的名字,second是elasticsearch中的index里面我们放进去的数据里面的字段名,也就是要在该字段中聚合出最大值
AggregationBuilder builder = AggregationBuilders.max("maxValue").field(column + ".keword");
//prepareSearch()传入要查询的index
SearchResponse response = client.prepareSearch(index).setTypes(type).addAggregation(builder).get();
//从查询结果中获取刚才定义的最大值的名称
Max max = response.getAggregations().get("maxValue");
System.out.println((int) max.getValue());
return (int) max.getValue();
}
/**
* 通过ID 更新数据
*
* @param jsonObject 要增加的数据
* @param index 索引,类似数据库
* @param type 类型,类似表
* @param id 数据ID
* @return
*/
public static void updateDataById(JSONObject jsonObject, String index, String type, String id) {
UpdateRequest updateRequest = new UpdateRequest();
updateRequest.index(index).type(type).id(id).doc(jsonObject);
client.update(updateRequest);
log.info("数据更新成功!");
}
/**
* 分词搜索
*
* @param index
* @param type
* @return
*/
public static List<Map<String, Object>> querySearch(String index, String type, String field, String text) {
SearchResponse response = client.prepareSearch(index)
.setTypes(type)
.setQuery(QueryBuilders.termQuery(field, text))
.setFrom(0)
.setSize(10)
.setExplain(true)//排序
.execute()
.actionGet();
SearchHits hits = response.getHits();
SearchHit[] searchHit = hits.getHits();
List<Map<String, Object>> list = new ArrayList<>();
for (int i = 0; i < searchHit.length; i++) {
Map<String, Object> map = searchHit[i].getSourceAsMap();
list.add(map);
}
return list;
}
/**
* 查询当前索引下的数据总量
*
* @param index
* @return
*/
public static long queryCountByIndex(String index) {
SearchResponse response = client.prepareSearch(index).execute().actionGet();
SearchHits searchHits = response.getHits();
log.info("查询到的数据总量:{}", searchHits.getTotalHits());
return searchHits.getTotalHits();
}
/**
* @Author: HESHANCUN
* @Description: 判断index指定type是否存在
*/
public boolean isTypeExist(String index, String type) {
return isIndexExist(index) ? client.admin()
.indices()
.prepareTypesExists(index)
.setTypes(type)
.execute()
.actionGet()
.isExists()
: false;
}
/**
* 判断索引是否存在
*
* @param index
* @return
*/
public static boolean isIndexExist(String index) {
IndicesExistsResponse inExistsResponse = client.admin().indices().exists(new IndicesExistsRequest(index)).actionGet();
if (inExistsResponse.isExists()) {
log.info("Index [" + index + "] is exist!");
} else {
log.error("Index [" + index + "] is not exist!");
}
return inExistsResponse.isExists();
}
}