package com.ssi.model; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.ssi.config.ElasticsearchConfig; import com.ssi.utils.GeoPosTransformUtil; import lombok.extern.slf4j.Slf4j; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * Description: * * @author LiXiaoCong * @version 2019/3/1 16:56 */ @Slf4j public class ElasticSearchModel { private final Logger logger = LoggerFactory.getLogger(ElasticSearchMetaModel.class); @Autowired protected TransportClient transportClient; @Autowired protected ElasticSearchMetaModel elasticSearchMetaModel; @Autowired protected ElasticsearchConfig elasticsearchConfig; protected BoolQueryBuilder createBooleanQueryBuilderWithChinaLocation() { return createBooleanQueryBuilderWithChinaLocation("longitude", "latitude"); } protected BoolQueryBuilder createBooleanQueryBuilderWithChinaLocation(String longitudeField, String latitudeField) { BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); //中国经纬度 boolQueryBuilder.must(QueryBuilders.rangeQuery(longitudeField).gte(73).lt(135)); boolQueryBuilder.must(QueryBuilders.rangeQuery(latitudeField).gte(4).lt(53)); return boolQueryBuilder; } protected Map extractSearchHits(SearchHits hits) { return extractSearchHits(hits, null, null, null); } protected Map extractSearchHits(SearchHits hits, String posType) { return extractSearchHits(hits, posType, "longitude", "latitude"); } protected List> extractSearchHits(SearchHit[] hits, String posType, String longitudeField, String latitudeField) { List> maps = Arrays.stream(hits).map(hit -> { Map sourceAsMap = hit.getSourceAsMap(); if (posType != null) { locationTypeChange(sourceAsMap, posType, longitudeField, latitudeField); } return sourceAsMap; }).collect(Collectors.toList()); return maps; } protected Map extractSearchHits(SearchHits hits, String posType, String longitudeField, String latitudeField) { Map res; long totalHits = hits.getTotalHits(); if (totalHits > 0) { res = Maps.newHashMapWithExpectedSize(3); res.put("total", totalHits); List> maps = extractSearchHits(hits.getHits(), posType, longitudeField, latitudeField); res.put("records", maps); res.put("size", maps.size()); } else { res = emptySearchHitResult(); } return res; } protected Map emptySearchHitResult() { Map res = Maps.newHashMapWithExpectedSize(3); res.put("total", 0); res.put("records", Lists.newArrayList()); res.put("size", 0); return res; } protected void locationTypeChange(Map sourceAsMap, String toType, String longitudeField, String latitudeField) { Object longitudeObj = sourceAsMap.get(longitudeField); Object latitudeObj = sourceAsMap.get(latitudeField); if (latitudeObj != null && longitudeObj != null) { double longitude = Double.parseDouble(longitudeObj.toString()); double latitude = Double.parseDouble(latitudeObj.toString()); double[] doubles = null; switch (toType) { //百度 case "bd09": doubles = GeoPosTransformUtil.wgs84tobd09(longitude, latitude); break; //高德 case "gcj02": doubles = GeoPosTransformUtil.wgs84togcj02(longitude, latitude); break; } if (doubles != null) { sourceAsMap.put(longitudeField, doubles[0]); sourceAsMap.put(latitudeField, doubles[1]); } } } /** * 移动过来的 */ protected SearchRequestBuilder newSearchRequestBuilder(Long startTime, Long endTime) { return newSearchRequestBuilder(startTime, endTime, elasticsearchConfig.getTypeName()); } protected SearchRequestBuilder newSearchRequestBuilder(Long startTime, Long endTime, String typeName) { SearchRequestBuilder requestBuilder; if (startTime == null && endTime == null) { requestBuilder = transportClient.prepareSearch(String.format("%s_2*", typeName)); } else { String[] indexs = getIndexs(startTime, endTime); if (indexs.length == 0) { requestBuilder = transportClient.prepareSearch(String.format("%s_2*", typeName)); logger.warn(String.format("在时间范围[%s,%s]内不存在%s的索引。", startTime, endTime, typeName)); } else { requestBuilder = transportClient.prepareSearch(indexs); } } return requestBuilder.setTypes(typeName); } protected String[] getIndexs(Long startTime, Long endTime) { return elasticSearchMetaModel.getIndexs(startTime, endTime, elasticsearchConfig.getTypeName(), 7, true); } }