Elasticsearch scroll java

package com.ygsoft.jvm.read;

import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchScrollRequestBuilder;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.script.Script;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.PipelineAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram.Order;
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilders;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ygsoft.jvm.dto.AggregatePoorFormulaDTO;
import com.ygsoft.jvm.dto.EsAggsVO;
import com.ygsoft.jvm.dto.EsQueryVO;
import com.ygsoft.jvm.type.AggregationType;
import com.ygsoft.jvm.type.EsAggregationType;
import com.ygsoft.jvm.type.EsQueryType;
import com.ygsoft.jvm.utils.StringUtils;

/**
 * ES Client
 * 
 * @author duhai
 * @date 2019年5月15日
 */
public class ElasticsearchUtils {

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

	private static TransportClient client;

	private final static String TIMESTAMP = "timestamp";

	private final static String DEVICEID = "deviceid";

	private final static String METRIC = "metric";

	private final static String VALUE = "value";

	public static final int BULK_SIZE = 5000;

	// 獲取線程池
	public static TransportClient getClient() {
		return client;
	}

	/**
	 * 
	 * @param hostName
	 *            elk集羣地址
	 * @param port
	 *            端口
	 * @param clusterName
	 *            集羣名稱
	 * @param poolSize
	 *            連接池
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public TransportClient init(final String hostName, final String port) {
		try {
			if (client == null) {
				// 配置信息
				Settings esSetting = Settings.builder()// 初始化
						.put("cluster.name", "elsearch")// 名字
						.put("client.transport.sniff", true)// 增加嗅探機制,找到ES集羣
						.put("thread_pool.search.size", 5)// 增加線程池個數,暫時設爲5
						.build();

				client = new PreBuiltTransportClient(esSetting);
				InetSocketTransportAddress inetSocketTransportAddress = new InetSocketTransportAddress(
						InetAddress.getByName(hostName), Integer.valueOf(port));
				client.addTransportAddresses(inetSocketTransportAddress);
			}
		} catch (Exception e) {
			logger.error("elasticsearch 客戶端 創建 error!!!", e);
		}
		return client;
	}

	/**
	 * 條件查詢出數據
	 * 
	 * @param index
	 *            es的查詢index
	 * @param type
	 *            VirtualMetricType表類型
	 * @param dto
	 *            聚合查詢參數對象
	 * @return
	 */
	public JSONArray caculateVirtualMetricQuery(final String index, final AggregatePoorFormulaDTO dto) {
		final JSONArray result = new JSONArray();
		/*
		 * 1.1、設置查詢
		 */
		final BoolQueryBuilder mainBoolQueryBuild = QueryBuilders.boolQuery();

		// 開始時間
		final String startTime = dto.getStartTime();
		// 結束時間
		final String endTime = dto.getEndTime();
		final EsQueryVO rangeVO = new EsQueryVO();
		rangeVO.setType(EsQueryType.RANGEQUERY);
		rangeVO.setStartTime(startTime);
		rangeVO.setEndTime(endTime);
		rangeVO.setCondition(TIMESTAMP);
		final QueryBuilder query1 = buildQueryBuild(rangeVO);
		mainBoolQueryBuild.filter(query1);// 設置查詢條件

		// 設備code
		final EsQueryVO deviceIdTermVO = new EsQueryVO();
		deviceIdTermVO.setType(EsQueryType.TERM);
		deviceIdTermVO.setCondition(DEVICEID);
		deviceIdTermVO.setValue(dto.getDeviceCode());
		final QueryBuilder deviceIdTermQuery = buildQueryBuild(deviceIdTermVO);
		mainBoolQueryBuild.filter(deviceIdTermQuery);

		// 測點列表
		final BoolQueryBuilder orBoolQueryBuild = QueryBuilders.boolQuery();
		// {"metricA":"3080"}
		final JSONObject params = dto.getParams();
		if (null == params || params.size() <= 0) {
			return result;
		}
		for (Entry<String, Object> entry : params.entrySet()) {
			// 測點
			final EsQueryVO metricTermVO = new EsQueryVO();
			metricTermVO.setType(EsQueryType.TERM);
			metricTermVO.setCondition(METRIC);
			metricTermVO.setValue(entry.getValue().toString());
			final QueryBuilder metricTermQuery = buildQueryBuild(metricTermVO);
			// 滿足一個要求的就可以
			orBoolQueryBuild.should(metricTermQuery);
		}

		mainBoolQueryBuild.filter(orBoolQueryBuild);
		final QueryBuilder builder1 = QueryBuilders.rangeQuery(VALUE).lt(-10000);
		final QueryBuilder builder2 = QueryBuilders.rangeQuery(VALUE).gt(10000);
		mainBoolQueryBuild.mustNot(builder1);
		mainBoolQueryBuild.mustNot(builder2);

		// 設置查詢 TODO
		SearchRequestBuilder requestBuilder = client.prepareSearch(index).setTypes(index)
				.setSearchType(SearchType.DFS_QUERY_THEN_FETCH);
		requestBuilder.setQuery(mainBoolQueryBuild);
		requestBuilder.addSort(SortBuilders.fieldSort("timestamp").order(SortOrder.DESC));
		requestBuilder.setFrom(0);
		requestBuilder.setScroll(TimeValue.timeValueMinutes(2));
		requestBuilder.setSize(10000);
		// requestBuilder.setExplain(true);

		logger.info("requestBuilder查詢:");
		logger.info(requestBuilder.toString());

		SearchResponse searchResponse = requestBuilder.execute().actionGet();
		do {
			Long time1 = System.currentTimeMillis();
			// 解析結果
			final SearchHit[] hits = searchResponse.getHits().getHits();
			if (hits.length > 0) {
				for (SearchHit hit : hits) {
					final Map<String, Object> map = hit.getSource();
					final JSONObject queryResultDTO = JSONObject.parseObject(JSONObject.toJSONString(map));
					result.add(queryResultDTO);
				}
			}
			Long time2 = System.currentTimeMillis();
			logger.info("1萬條添加完成時間" + (time2 - time1));
			SearchScrollRequestBuilder searchScrollRequestBuilder = client
					.prepareSearchScroll(searchResponse.getScrollId()).setScroll(TimeValue.timeValueMinutes(4));
			logger.info("searchScrollRequestBuilder查詢:");
			logger.info(requestBuilder.toString());
			searchResponse = searchScrollRequestBuilder.execute().actionGet();
			logger.info("1萬查詢完成時間" + (System.currentTimeMillis() - time2));
		} while (searchResponse.getHits().getHits().length != 0);
		logger.info("-----------------------全部查詢" + result.size() + "條");
		return result;
	}

	/**
	 * 構建查詢語句
	 * 
	 * @param vo
	 *            查詢參數
	 * @return QueryBuilder 查詢結構
	 */
	public QueryBuilder buildQueryBuild(final EsQueryVO vo) {
		QueryBuilder builder = null;
		if (vo.getType() == EsQueryType.RANGEQUERY) {
			builder = QueryBuilders.rangeQuery(vo.getCondition()).gte(vo.getStartTime()).lte(vo.getEndTime());
		} else if (vo.getType() == EsQueryType.TERM) {
			builder = QueryBuilders.termQuery(vo.getCondition(), vo.getValue());
		} else if (vo.getType() == EsQueryType.TERMS) {
			builder = QueryBuilders.termsQuery(vo.getCondition(), vo.getMultiValue());
		}

		return builder;
	}

	/**
	 * 設置聚合
	 * 
	 * @param vo
	 * @return
	 */
	public AggregationBuilder buildAggregationModel(final EsAggsVO vo) {
		AggregationBuilder aggregation = null;
		if (vo.getType() == EsAggregationType.DATEHISTOGRAM) {
			final DateHistogramInterval interval = new DateHistogramInterval(vo.getInterval());
			aggregation = AggregationBuilders.dateHistogram(AggregationType.DATE_HISTOGRAM.getName())
					.field(vo.getValue()).format(vo.getFormat()).dateHistogramInterval(interval)
					.minDocCount(vo.getMinDocCount()).order(vo.getOrder() == 0 ? Order.KEY_ASC : Order.KEY_DESC);
		} else if (vo.getType() == EsAggregationType.MAX) {
			aggregation = AggregationBuilders.max(AggregationType.MAX.getName()).field(vo.getValue());
		} else if (vo.getType() == EsAggregationType.MIN) {
			aggregation = AggregationBuilders.min(AggregationType.MIN.getName()).field(vo.getValue());
		} else if (vo.getType() == EsAggregationType.SUM) {
			aggregation = AggregationBuilders
					.sum(StringUtils.isEmpty(vo.getBucketStr()) ? AggregationType.SUM.getName() : vo.getBucketStr())
					.field(vo.getValue());
		} else if (vo.getType() == EsAggregationType.AVG) {
			aggregation = AggregationBuilders.avg(AggregationType.AVG.getName()).field(vo.getValue());
		} else if (vo.getType() == EsAggregationType.FILTER) {
			final QueryBuilder build = QueryBuilders.termQuery(vo.getKey(), vo.getValue());
			aggregation = AggregationBuilders.filter(vo.getValue(), build);
		} else if (vo.getType() == EsAggregationType.TERMS) {
			aggregation = AggregationBuilders.terms(AggregationType.TERMS.getName()).field(vo.getKey()).size(100);
		}

		return aggregation;
	}

	/**
	 * 設置聚合
	 * 
	 * @param vo
	 * @return
	 */
	public PipelineAggregationBuilder buildPipelineAggregationModel(final EsAggsVO vo) {
		PipelineAggregationBuilder aggregation = null;
		String bucketName = vo.getBucketStr();
		if (vo.getType() == EsAggregationType.MAX_BUCKET) {
			aggregation = PipelineAggregatorBuilders.maxBucket(bucketName, vo.getBucketName());
		} else if (vo.getType() == EsAggregationType.MIN_BUCKET) {
			aggregation = PipelineAggregatorBuilders.minBucket(bucketName, vo.getBucketName());
		} else if (vo.getType() == EsAggregationType.AVG_BUCKET) {
			aggregation = PipelineAggregatorBuilders.avgBucket(bucketName, vo.getBucketName());
		} else if (vo.getType() == EsAggregationType.SUM_BUCKET) {
			aggregation = PipelineAggregatorBuilders.sumBucket(bucketName, vo.getBucketName());
		} else if (vo.getType() == EsAggregationType.POOR_FORMULE) {
			Map<String, String> bucketsPathsMap = new HashMap<String, String>();
			if (null == vo.getBucketsPathsMap()) {
				bucketsPathsMap.put(AggregationType.MAX.getName(), AggregationType.MAX.getName());
				bucketsPathsMap.put(AggregationType.MIN.getName(), AggregationType.MIN.getName());
			} else {
				bucketsPathsMap = vo.getBucketsPathsMap();
			}

			String model = vo.getBucketModel();
			if (StringUtils.isEmpty(model)) {
				model = String.format("params.%s - params.%s", AggregationType.MAX.getName(),
						AggregationType.MIN.getName());
			}

			String name = vo.getBucketStr();
			if (null == name || name.isEmpty()) {
				name = AggregationType.POOR_FORMULA.getName();
			}

			final Script script = new Script(model);
			aggregation = PipelineAggregatorBuilders.bucketScript(name, bucketsPathsMap, script);
		}

		return aggregation;
	}

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章