java操作elasticSearch

1 .maven 依赖

	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
	</dependency>
	<dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
        <version>7.5.1</version>
        <exclusions>
            <exclusion>
                <groupId>org.elasticsearch</groupId>
                <artifactId>elasticsearch</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>7.5.1</version>
    </dependency>

2.初始化索引

		@Autowired
		private RestHighLevelClient client;
 		private void createGeomIndex(String indexName, String geomType) {
 			//String indexName = "my_index";
 			CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);
            Map<String, Object> properties = new HashMap<>();
            //空间字段
            Map<String, Object> geom = new HashMap<>();
            //geomType分为两种geo_point和geo_shape
            //String geomType="geo_point";
            geom.put("type", geomType);
            properties.put("geom", geom);
            //关键字,一般用于模糊查询
            Map<String, Object> contentMap = new HashMap<>();
            contentMap.put("type", "text");
            //最小颗粒度分词
            contentMap.put("analyzer", "ik_max_word");
            //智能分词
            contentMap.put("search_analyzer", "ik_smart");
            properties.put("content", contentMap);
            //把配置塞到映射中
            Map<String, Object> mapping = new HashMap<>();
            mapping.put("properties", properties);
            createIndexRequest.mapping(mapping);
            //操作索引的客户端
            IndicesClient indices = client.indices();
            //执行创建索引库
            CreateIndexResponse response = indices.create(createIndexRequest, RequestOptions.DEFAULT);
       }

3.初始化数据

/**
 * 将数据插入ES
 *
 * @param tableName
 * @param dataList
 */
public static void insertEsData(String indexName, String pk, List dataList) {
    BulkProcessor bulkProcessor =ElasticQueryUtil .getBulkProcessor(client);
    for (Object object : dataList) {
        IndexRequest indexRequest = new IndexRequest(tableName);
        Map<String, Object> data = (Map<String, Object>) object;
        if (data != null && StringUtils.isNotBlank(pk) && data.get(pk) != null) {
            indexRequest.id(data.get(pk).toString());
        }
        indexRequest.source(JSON.toJSONString(object), XContentType.JSON);
        bulkProcessor.add(indexRequest);
    }
    bulkProcessor.flush();
}
//获取数据源data,并插入2中创建的es索引中
public void initEsData(){
	List<Map<String, Object>> data = new ArrayList<>();
	//添加所需数据,或者使用实体转换成map
	//map中字段名可任意,但是如果与创建索引时propertiesMap中字段名相同,字段类型会按照propertiesMap创建
	//data.add();
	//索引名
	String indexName= “my_index”;
	//主键字段名
	String pk="id";
	insertEsData(,indexName,pk,data);
}

4.查询数据工具类

import gis.config.AsyncSupportConfig;
import org.elasticsearch.action.ActionListener;
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.search.*;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.client.core.CountResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
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.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.UpdateByQueryRequest;
import org.elasticsearch.script.Script;
import org.elasticsearch.search.Scroll;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;

public class ElasticQueryUtil {
    private static Logger log = LoggerFactory.getLogger(ElasticQueryUtil.class);

    /**
     * 方法说明: 查询索引所有数据
     *
     * @param client             es客户端对象
     * @param index              索引
     * @param asyncSupportConfig 异步配置线程池配置
     * @return java.util.List<java.util.Map < java.lang.String, java.lang.Object>>
     * @date 2023/5/8 9:50
     * @author win
     */
    public static List<Map<String, Object>> searchAll(RestHighLevelClient client, String index, AsyncSupportConfig asyncSupportConfig) {
        List<Map<String, Object>> result = new ArrayList();
        Integer maxQuerySize = 10000;
        //查询算法
        try {
            Scroll scroll = new Scroll(new TimeValue(60000));
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            searchSourceBuilder.from(0);
            //es默认最多查询前10000条数据
            searchSourceBuilder.size(maxQuerySize);
            SearchRequest searchRequest = new SearchRequest();
            searchRequest.indices(index);
            searchRequest.source(searchSourceBuilder).scroll(scroll);
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            for (SearchHit hit : searchResponse.getHits()) {
                result.add(hit.getSourceAsMap());
            }
            List<String> scrollIdList = new ArrayList<>();
            //获取第一次查询的scrollId
            String scrollId = searchResponse.getScrollId();
            scrollIdList.add(scrollId);
            SearchHit[] searchHits = searchResponse.getHits().getHits();
            //上一次返回值searchHits.length=maxQuerySize
            while (searchHits != null && searchHits.length == maxQuerySize) {
                //滚动查询
                SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
                scrollRequest.scroll(scroll);
                searchResponse = client.scroll(scrollRequest, RequestOptions.DEFAULT);
                scrollId = searchResponse.getScrollId();
                scrollIdList.add(scrollId);
                searchHits = searchResponse.getHits().getHits();
                if (searchHits != null && searchHits.length > 0) {
                    for (SearchHit hit : searchHits) {
                        result.add(hit.getSourceAsMap());
                    }
                }
            }
            //异步线程清除scrollId
            //根据实际情况,使用,也可以删除
            asyncSupportConfig.asyncTaskExecutor().execute(() -> {
                //清除所有scrollId,防止es的scrollId积压,超过一定限制时会报错
                try {
                    ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
                    clearScrollRequest.scrollIds(scrollIdList);
                    ClearScrollResponse clearScrollResponse = client.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);
                    boolean succeeded = clearScrollResponse.isSucceeded();
                    log.info("清除scrollId:{}==>>{}", scrollIdList, succeeded ? "成功!" : "失败!");
                } catch (Exception e) {
                    log.error("清除scrollId:{}==>>失败,原因:{}", scrollIdList, e.getMessage());
                }
            });

        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询索引{}所有数据失败,原因:{}", index, e.getMessage());
        }
        return result;
    }

    /**
     * 方法说明: es查询
     *
     * @param client           es客户端对象
     * @param index            索引名称
     * @param boolQuery        条件查询
     * @param geomQueryBuilder 空间过滤
     * @param maxReturnNum     单次查询最大返回值
     * @return java.util.List
     * @date 2023/5/8 9:49
     * @author win
     */
    public static List search(RestHighLevelClient client, String index, BoolQueryBuilder boolQuery, QueryBuilder geomQueryBuilder, Integer maxReturnNum) throws Exception {
        SearchSourceBuilder searchSourceBuilder = getSourceBuilder(boolQuery, geomQueryBuilder);
        log.info("searchSourceBuilder " + searchSourceBuilder);
        searchSourceBuilder.from(0);
        searchSourceBuilder.size(maxReturnNum);
        //执行es查询
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices(index);
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        List list = new ArrayList();
        //返回值解析
        for (SearchHit hit : searchResponse.getHits()) {
            list.add(hit.getSourceAsMap());
        }
        return list;
    }

    /**
     * 方法说明: 获取查询条件
     *
     * @param boolQuery
     * @param geomQueryBuilder
     * @return org.elasticsearch.search.builder.SearchSourceBuilder
     * @date 2023/5/8 9:48
     * @author win
     */
    public static SearchSourceBuilder getSourceBuilder(BoolQueryBuilder boolQuery, QueryBuilder geomQueryBuilder) {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        if (boolQuery == null) {
            boolQuery = QueryBuilders.boolQuery();
        }
        //空间查询条件作为filter过滤
        if (geomQueryBuilder != null) {
            boolQuery.filter(geomQueryBuilder);
        }
        searchSourceBuilder.query(boolQuery);
        return searchSourceBuilder;
    }

    /**
     * 方法说明: es数量查询
     *
     * @param client
     * @param index
     * @param boolQuery
     * @param geomQueryBuilder
     * @return java.lang.Long
     * @date 2023/5/8 9:48
     * @author win
     */
    public static Long searchCount(RestHighLevelClient client, String index, BoolQueryBuilder boolQuery, QueryBuilder geomQueryBuilder) throws Exception {
        SearchSourceBuilder searchSourceBuilder = getSourceBuilder(boolQuery, geomQueryBuilder);
        log.info("searchSourceBuilder " + searchSourceBuilder);
        CountRequest countRequest = new CountRequest();
        countRequest.indices(index);
        countRequest.source(searchSourceBuilder);
        CountResponse countResponse = client.count(countRequest, RequestOptions.DEFAULT);
        long count = countResponse.getCount();
        return count;
    }

    /**
     * 方法说明: es批量请求
     *
     * @param multiRequest
     * @param index
     * @param boolQuery
     * @param geomQueryBuilder
     * @param maxReturnNum
     * @return void
     * @date 2023/5/8 9:47
     * @author win
     */
    public static void multiRequest(MultiSearchRequest multiRequest, String index, BoolQueryBuilder boolQuery, QueryBuilder geomQueryBuilder, Integer maxReturnNum) throws Exception {
        SearchSourceBuilder searchSourceBuilder = getSourceBuilder(boolQuery, geomQueryBuilder);
        log.info("searchSourceBuilder " + searchSourceBuilder);
        searchSourceBuilder.from(0);
        searchSourceBuilder.size(maxReturnNum);
        //执行es查询
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices(index);
        searchRequest.source(searchSourceBuilder);
        multiRequest.add(searchRequest);
    }

    /**
     * 方法说明: 索引是否存在
     *
     * @param client
     * @param indexName
     * @return boolean
     * @date 2023/5/8 9:47
     * @author win
     */
    public static boolean isExistsIndex(RestHighLevelClient client, String indexName) {
        GetIndexRequest existsRequest = new GetIndexRequest(indexName);
        try {
            return client.indices().exists(existsRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }
    public static BulkProcessor getBulkProcessor(RestHighLevelClient client) {
        BulkProcessor bulkProcessor = null;
        try {
            BulkProcessor.Listener listener = new BulkProcessor.Listener() {
                @Override
                public void beforeBulk(long executionId, BulkRequest request) {
                    log.info("Try to insert data number : "
                            + request.numberOfActions());
                }
                @Override
                public void afterBulk(long executionId, BulkRequest request,
                                      BulkResponse response) {
                    log.info("************** Success insert data number : "
                            + request.numberOfActions() + " , id: " + executionId);
                }

                @Override
                public void afterBulk(long executionId, BulkRequest request, Throwable failure) {
                    log.error("Bulk is unsuccess : " + failure + ", executionId: " + executionId);
                }
            };
            BiConsumer<BulkRequest, ActionListener<BulkResponse>> bulkConsumer = (request, bulkListener) -> client
                    .bulkAsync(request, RequestOptions.DEFAULT, bulkListener);
            BulkProcessor.Builder builder = BulkProcessor.builder(bulkConsumer, listener);
            builder.setBulkActions(5000);
            builder.setBulkSize(new ByteSizeValue(100L, ByteSizeUnit.MB));
            builder.setConcurrentRequests(10);
            builder.setFlushInterval(TimeValue.timeValueSeconds(100L));
            builder.setBackoffPolicy(BackoffPolicy.constantBackoff(TimeValue.timeValueSeconds(1L), 3));
            // 注意点:让参数设置生效
            bulkProcessor = builder.build();

        } catch (Exception e) {
            e.printStackTrace();
            try {
                bulkProcessor.awaitClose(100L, TimeUnit.SECONDS);
            } catch (Exception e1) {
                log.error(e1.getMessage());
            }
        }
        return bulkProcessor;
    }

    public static void updateByQuery(RestHighLevelClient client,String indexName, BoolQueryBuilder boolQueryBuilder, String updateScript,Map<String, Object> params) throws IOException {
        UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest(indexName);
        //设置分片并行
        updateByQueryRequest.setSlices(2);
        //设置版本冲突时继续执行
        updateByQueryRequest.setConflicts("proceed");
        //设置更新完成后刷新索引 ps很重要如果不加可能数据不会实时刷新
        updateByQueryRequest.setRefresh(true);
        //查询条件
        updateByQueryRequest.setQuery(boolQueryBuilder);
        //设置要修改的内容可以多个值多个用;隔开
        Script script = new Script(Script.DEFAULT_SCRIPT_TYPE, Script.DEFAULT_SCRIPT_LANG, updateScript, params);
        updateByQueryRequest.setScript(script);
        updateByQueryRequest.setIndicesOptions(IndicesOptions.LENIENT_EXPAND_OPEN);
        client.updateByQuery(updateByQueryRequest, RequestOptions.DEFAULT);
    }
}

5.查询条件

常规条件查询,根据es的语法,用QueryBuilders生成对用的QueryBuilder对象即可,如: QueryBuilders.termQuery()、matchQuery等。
这里讲一下空间条件查询。在我们保存的数据中,如果是存有geom字段,即保存的数据是具有空间坐标关系的数据时,就可以根据空间范围,做数据的筛选功能。
无论时geomJson还是WKT格式的空间字段,数据中都具有经纬度等坐标。每一种空间类型都会有一个 坐标的数组。这里以WKT格式做个简单的例子:
POLYGON((121.32506989602659 31.223014372314935,121.48366224813478 31.228140808580477,121.5190866566813 31.120893846786345,121.31144512350873 31.089162799223104,121.25422107893358 31.172667326376356,121.32506989602659 31.223014372314935))
MULTIPOLYGON(((121.625111 31.634524,121.63392 31.631864,121.635249 31.630876,121.636897 31.628641,121.636965 31.628138,121.636421 31.627199,121.631163 31.620245,121.629288 31.618096,121.628423 31.614926,121.627587 31.615062,121.626782 31.611252,121.625972 31.61002,121.624216 31.600292,121.621436 31.587459,121.61095 31.591749,121.607875 31.592811,121.606856 31.582994,121.603847 31.563096,121.601855 31.559518,121.598211 31.561065,121.596743 31.558434,121.596349 31.558066,121.596064 31.556724,121.595422 31.556179,121.592779 31.551205,121.590063 31.546771,121.59001 31.546376,121.586763 31.541009,121.585807 31.539068,121.584595 31.537232,121.582533 31.533441,121.56353 31.541938,121.563815 31.543127,121.562865 31.54408,121.559886 31.545109,121.560124 31.546846,121.559411 31.547394,121.558224 31.542685,121.539372 31.550556,121.538186 31.549131,121.536526 31.550325,121.535814 31.551279,121.538661 31.556745,121.544323 31.552651,121.54672 31.55637,121.547253 31.556309,121.550542 31.581726,121.56057 31.576592,121.565098 31.595955,121.565439 31.596869,121.572353 31.630796,121.574469 31.635523,121.593665 31.635813,121.59434 31.635994,121.599435 31.635531,121.599782 31.636927,121.61295 31.637118,121.614259 31.637733,121.625111 31.634524)),
((121.670974 31.642868,121.6875 31.635897,121.686045 31.632211,121.699107 31.627443,121.714597 31.621042,121.725554 31.616059,121.729877 31.613032,121.730217 31.613363,121.738103 31.610558,121.739769 31.609608,121.750239 31.604852,121.754283 31.602473,121.7569 31.60057,121.757613 31.600332,121.755945 31.599458,121.752436 31.594398,121.750167 31.595636,121.750643 31.596588,121.739697 31.602771,121.739221 31.602295,121.736603 31.603959,121.72946 31.605143,121.727555 31.603,121.718808 31.606657,121.718606 31.606311,121.718177 31.606501,121.71838 31.606823,121.717463 31.607226,121.707306 31.614157,121.69825 31.617712,121.689907 31.6127,121.689191 31.613412,121.685615 31.610788,121.6849 31.611501,121.6849 31.612452,121.695867 31.618421,121.681325 31.620774,121.677172 31.621882,121.674984 31.618166,121.673181 31.618434,121.672781 31.61799,121.672952 31.616963,121.670535 31.61563,121.669076 31.61557,121.66344 31.618886,121.658291 31.621547,121.652785 31.623522,121.651812 31.622021,121.65124 31.622377,121.651498 31.622749,121.650697 31.623204,121.650711 31.623418,121.650125 31.623917,121.650468 31.624489,121.646865 31.626225,121.646593 31.625881,121.646253 31.62581,121.643705 31.626577,121.642407 31.627281,121.641483 31.627349,121.641897 31.627893,121.643241 31.627467,121.648046 31.635841,121.657956 31.632417,121.65777 31.631988,121.665522 31.628091,121.668026 31.633492,121.66179 31.636164,121.660159 31.637403,121.649883 31.641525,121.653995 31.649773,121.670974 31.642868)),
((121.535998 31.715353,121.532974 31.711483,121.53154 31.714379,121.521711 31.718523,121.519947 31.713126,121.510863 31.717518,121.510219 31.715583,121.509109 31.71606,121.509713 31.718045,121.504687 31.720023,121.506667 31.724633,121.50847 31.72954,121.510521 31.733389,121.511386 31.733398,121.525398 31.727028,121.538489 31.718451,121.535998 31.715353)))
以上多边形或者多多边形,赋值给String字符串变量;

//import org.elasticsearch.common.geo.GeoPoint;   

   	 private static  GeometryFactory geometryFactory = new GeometryFactory();
	 private static  WKTReader reader = new WKTReader(geometryFactory);
	 public GeoPolygonQueryBuilder readerWkt(String geom) throws Exception {
	 	//转成Geometry 对象
 		Geometry geometry =reader.read(geom);
 		//获取对象的坐标点
 		Coordinate[] coordinates = geometry.getCoordinates();
 		List<GeoPoint> list = new ArrayList<>();
        for (Coordinate coordinate : coordinates) {
            list.add(new GeoPoint(coordinate.y, coordinate.x));
        }
 		//转成es的GeoPoint,创建queryBuilder
 		 GeoPolygonQueryBuilder geomQueryBuilder =QueryBuilders.geoPolygonQuery(field, list );
 		 return geomQueryBuilder ;

 }
 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值