package com.tools.es.util;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import org.apache.commons.collections.CollectionUtils;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.bulk.BulkItemResponse;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.WriteRequest.RefreshPolicy;
import org.elasticsearch.action.update.UpdateRequestBuilder;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryStringQueryBuilder;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.index.reindex.BulkIndexByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryAction;
import org.elasticsearch.index.reindex.DeleteByQueryRequestBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHitField;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.bucket.range.Range;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.api.dto.SamplingResultVO;
import com.server.jdbc.bean.IndexTableEntity;
import com.server.tools.es.dataware.BaseInfo;
import com.server.tools.es.dataware.ErrorDetail;
import com.server.tools.es.dataware.Filter;
import com.server.tools.es.dataware.FilterDetail;
import com.server.tools.es.dataware.Query;
import com.server.tools.es.dataware.QueryColumn;
import com.server.tools.es.dataware.QueryOrder;
import com.server.tools.es.dataware.ResultMsg;
import com.server.tools.es.dto.Column;
import com.server.tools.es.dto.DataSet;
import com.server.tools.es.enumeration.EnumExtendDate;
import com.server.tools.es.type.ColType;
/**
* ES 工具类
*
* @author duhai
* @version 1.0
*/
@Component
public class ElasticsearchUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(ElasticsearchUtils.class);
@Autowired
private TransportClient transportClient;
private static TransportClient client;
@PostConstruct
public void init() {
client = this.transportClient;
}
private final static String TIMESTAMP = "timestamp";
public static final String FLAG_DIMENSION = "dimention_";
public static final String FLAG_COMPARSION = "comparsion_";
public static final String FLAG_MEASURE = "measure_";
public static final String FLAG_ENDFIX_KEYWORD = "";
public static final String FLAG_ENDFIX_DOUBLE_STRING = "_dstr";
public static final String FLAG_ENDFIX_TEXT_ANALYSE = "word";
@Value("${sampling.index}")
private String indexName;
public static final int BULK_SIZE = 10000;
/**
* 创建索引
*
* @param columnList
* @param indexName
*/
public void createPhyTable(final List columnList, final String indexName, final boolean flag) {
if (!existTable(indexName)) {
Settings esSetting = Settings.builder().put("index.refresh_interval", "30s")
// 索引刷新间隔调整
// .put("index.translog.durability", "async")
// //如果对数据丢失有一定的容忍,可以打开async模式
.put("index.translog.sync_interval", "30s").put("index.translog.flush_threshold_size", "1gb")
.put("index.merge.scheduler.max_thread_count", 1).build();
// 创建索引
client.admin().indices().prepareCreate(indexName).setSettings(esSetting).execute().actionGet();
}
// 创建索引结构
XContentBuilder builder = null;
try {
builder = XContentFactory.jsonBuilder().startObject().startObject(indexName).startObject("_all")
.field("enabled", false).endObject()
// .startObject("_source").field("enabled",false).endObject()
.startObject("properties");
for (Column colume : columnList) {
builder.startObject(colume.getColName());
if (ColType.TEXT == colume.getColType().intValue()) {
builder.field("type", "string");
builder.field("index", "not_analyzed").endObject();
/*
* builder.startObject("fields"); builder.startObject(FLAG_ENDFIX_TEXT_ANALYSE);
* builder.field("type", "text"); builder.field("fielddata", true); builder.field("analyzer",
* "not_analyzed"); builder.field("search_analyzer", "not_analyzed"); builder.field("index",
* "analyzed").endObject().endObject();
*/
} else if (ColType.NUMBER == colume.getColType().intValue()) {
builder.field("type", "double");
builder.field("index", "not_analyzed").endObject();
if (flag) {
builder.startObject(colume.getColName() + FLAG_ENDFIX_DOUBLE_STRING);
builder.field("type", "string");
builder.field("index", "not_analyzed").endObject();
}
} else if (ColType.DATE == colume.getColType().intValue()) {
builder.field("type", "date").field("format", "yyyy/MM/dd||yyyy/MM/dd HH:mm:ss||epoch_millis");
builder.field("index", "not_analyzed").endObject();
} /*
* else if (ColType.TEXT_ANALYSE == colume.getColType().intValue()) { builder.startObject("fields");
* builder.startObject(FLAG_ENDFIX_TEXT_ANALYSE); builder.field("type", "text");
* builder.field("fielddata", true); builder.field("analyzer", "not_analyzed");
* builder.field("search_analyzer", "not_analyzed"); builder.field("index",
* "analyzed").endObject().endObject().endObject(); }
*/
}
builder.endObject().endObject().endObject();
} catch (IOException e) {
LOGGER.error("创建索引结构失败: " + indexName);
throw new RuntimeException("创建索引结构失败: " + indexName, e);
}
PutMappingRequest mapping = Requests.putMappingRequest(indexName).type(indexName).source(builder);
client.admin().indices().putMapping(mapping).actionGet();
// client.close();
LOGGER.info("Create Index Structure Succeed:" + indexName);
}
/**
* 创建索引2
*
* @param columnList
* @param indexName
*/
public void createPhyTable2(final List columnList, final String indexName, final boolean flag) {
if (!existTable(indexName)) {
Settings esSetting = Settings.builder().put("index.refresh_interval", "30s")
// 索引刷新间隔调整
// .put("index.translog.durability", "async")
// //如果对数据丢失有一定的容忍,可以打开async模式
.put("index.translog.sync_interval", "30s").put("index.translog.flush_threshold_size", "1gb")
.put("index.merge.scheduler.max_thread_count", 1).build();
// 创建索引
client.admin().indices().prepareCreate(indexName).setSettings(esSetting).execute().actionGet();
}
// 创建索引结构
XContentBuilder builder = null;
try {
builder = XContentFactory.jsonBuilder().startObject().startObject(indexName).startObject("_all")
.field("enabled", false).endObject()
// .startObject("_source").field("enabled",false).endObject()
.startObject("properties");
for (Column colume : columnList) {
builder.startObject(colume.getColName());
if (ColType.TEXT == colume.getColType().intValue()) {
builder.field("type", "string");
builder.field("index", "not_analyzed").endObject();
/*
* builder.startObject("fields"); builder.startObject(FLAG_ENDFIX_TEXT_ANALYSE);
* builder.field("type", "text"); builder.field("fielddata", true); builder.field("analyzer",
* "not_analyzed"); builder.field("search_analyzer", "not_analyzed"); builder.field("index",
* "analyzed").endObject().endObject();
*/
} else if (ColType.NUMBER == colume.getColType().intValue()) {
builder.field("type", "double");
builder.field("index", "not_analyzed").endObject();
if (flag) {
builder.startObject(colume.getColName() + FLAG_ENDFIX_DOUBLE_STRING);
builder.field("type", "string");
builder.field("index", "not_analyzed").endObject();
}
} else if (ColType.DATE == colume.getColType().intValue()) {
builder.field("type", "date").field("format", "yyyy/MM/dd||yyyy/MM/dd HH:mm:ss||epoch_millis");
builder.field("index", "not_analyzed").endObject();
} /*
* else if (ColType.TEXT_ANALYSE == colume.getColType().intValue()) { builder.startObject("fields");
* builder.startObject(FLAG_ENDFIX_TEXT_ANALYSE); builder.field("type", "text");
* builder.field("fielddata", true); builder.field("analyzer", "not_analyzed");
* builder.field("search_analyzer", "not_analyzed"); builder.field("index",
* "analyzed").endObject().endObject().endObject(); }
*/
}
builder.endObject().endObject().endObject();
} catch (IOException e) {
LOGGER.error("创建索引结构失败: " + indexName);
throw new RuntimeException("创建索引结构失败: " + indexName, e);
}
PutMappingRequest mapping = Requests.putMappingRequest(indexName).type(indexName).source(builder);
client.admin().indices().putMapping(mapping).actionGet();
// client.close();
LOGGER.info("Create Index Structure Succeed:" + indexName);
}
/**
* 判断索引是否存在
*
* @param table
* @return
*/
public boolean existTable(final String table) {
IndicesExistsRequest request = new IndicesExistsRequest(table);
IndicesExistsResponse response = client.admin().indices().exists(request).actionGet();
if (response.isExists()) {
return true;
}
return false;
}
/**
* 写入历史数据
*
* @param resultList
* voList
* @return ResultMsg 结果
*/
public ResultMsg saveSampling(final List resultList) {
final ResultMsg resultMsg = new ResultMsg();
BulkRequestBuilder bulkRequest = client.prepareBulk();
bulkRequest.setRefreshPolicy(RefreshPolicy.IMMEDIATE);
int count = 0;
int len = resultList.size();
try {
for (int i = 0; i < len; i++) {
final SamplingResultVO vo = resultList.get(i);
final XContentBuilder builder = XContentFactory.jsonBuilder().startObject();
final String id = vo.getId();
builder.field("timestamp", vo.getTimestamp());
builder.field("deviceId", vo.getDeviceId());
builder.field("metric", vo.getMetric());
builder.field("indexName", vo.getIndexName());
builder.field("domain", vo.getDomain());
builder.field("rule", vo.getRule());
builder.field("top", vo.getTop());
builder.field("height", vo.getHeight());
builder.field("flat", vo.getFlat());
builder.field("valley", vo.getValley());
builder.field("topDj", vo.getTopDj());
builder.field("heightDj", vo.getHeightDj());
builder.field("flatDj", vo.getFlatDj());
builder.field("valleyDj", vo.getValleyDj());
builder.endObject();
IndexRequestBuilder requestBuilder = client.prepareIndex("sampling", indexName, id).setSource(builder);
bulkRequest.add(requestBuilder);
count++;
if (count % BULK_SIZE == 0) {
BulkResponse bulkResponse = bulkRequest.execute().actionGet();
if (bulkResponse.hasFailures()) {
LOGGER.error("导入索引数据失败: " + indexName);
LOGGER.error("导入索引数据失败: " + bulkResponse.buildFailureMessage());
resultMsg.setHasFailures(true);
BulkItemResponse[] responses = bulkResponse.getItems();
for (int k = 0; k < responses.length; k++) {
BulkItemResponse response = responses[k];
if (response.isFailed()) {
ErrorDetail errorDetail = new ErrorDetail();
errorDetail.setIndex(k + (i / BULK_SIZE));
errorDetail.setId(response.getId());
errorDetail.setMsg(response.getFailureMessage());
resultMsg.addError(errorDetail);
}
}
}
bulkRequest = client.prepareBulk();
bulkRequest.setRefreshPolicy(RefreshPolicy.IMMEDIATE);
count = 0;
}
}
if (count > 0) {
BulkResponse bulkResponse = bulkRequest.execute().actionGet();
if (bulkResponse.hasFailures()) {
LOGGER.error("导入索引数据失败: " + indexName);
LOGGER.error("导入索引数据失败: " + bulkResponse.buildFailureMessage());
resultMsg.setHasFailures(true);
BulkItemResponse[] responses = bulkResponse.getItems();
for (int k = 0; k < responses.length; k++) {
BulkItemResponse response = responses[k];
if (response.isFailed()) {
ErrorDetail errorDetail = new ErrorDetail();
errorDetail.setIndex(k + (len / BULK_SIZE));
errorDetail.setId(response.getId());
errorDetail.setMsg(response.getFailureMessage());
resultMsg.addError(errorDetail);
}
}
}
}
return resultMsg;
} catch (Exception e) {
LOGGER.error("导入索引数据失败: " + indexName);
throw new RuntimeException("导入索引数据失败: " + indexName, e);
} finally {
bulkRequest.setRefreshPolicy(RefreshPolicy.IMMEDIATE);
}
}
/**
* 数据处理(写入)
*
* @param operator
* @param dataSet
* @return
*/
public ResultMsg dealDataHelp(final DataSet dataSet) {
String indexName = dataSet.getPhyName();
List columnList = dataSet.getCols();
List