Elasticsearch-经纬度查询(8.x)
目录
一、开发环境
二、pom文件
三、ES配置文件
四、ES相关字段
五、ES半径查询
ES的字段类型:geo_point,可以实现以一个点为中心的半径查询(geo_distance query)
ES地理位置查询:
- 半径查询(geo_distance query)
- 查询指定矩形内的数据(geo_bounding_box query)
- 查询指定多边形内的数据(geo_polygon query)
官方文档:Geo queries | Elasticsearch Guide [8.14] | Elastic
本案例实现以某个点的经纬,查询半径查询,并计算出其他点和中心点的距离
一、开发环境
工具 版本 JDK 21 SpringBoot 3.2.4 ElasticSearch 8.13.2 二、pom文件
co.elastic.clients elasticsearch-java 8.13.2三、ES配置文件
properties:
import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import java.util.List; /** * ES 配置属性 * * @author meng * @date 2024-05-07 */ @Data @ConfigurationProperties(prefix = "es") public class ElasticsearchProperties { /** * es 请求方式 */ private String scheme; /** * es 集群host ip 地址 */ private List hosts; /** * es 账号 */ private String username; /** * es 密码 */ private String password; /** * es 连接超时时间 */ private Integer connectTimeOut; /** * es socket 连接超时时间 */ private Integer socketTimeOut; /** * es 请求超时时间 */ private Integer connectionRequestTimeOut; /** * es 最大连接数 */ private Integer maxConnectNum; /** * es 每个路由的最大连接数 */ private Integer maxConnectNumPerRoute; }config:
import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.json.jackson.JacksonJsonpMapper; import co.elastic.clients.transport.ElasticsearchTransport; import co.elastic.clients.transport.rest_client.RestClientTransport; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.ssl.TrustStrategy; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestClientBuilder; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.net.ssl.SSLContext; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.time.Duration; /** * ES 配置类,当 es.enable=true 时自动配置 * * @author meng * @date 2024-05-07 */ @Slf4j @Configuration @EnableConfigurationProperties(value = ElasticsearchProperties.class) @ConditionalOnProperty(prefix = "es", name = "enable") public class ElasticsearchConfig { @Bean(name = "ElasticsearchClient") public ElasticsearchClient initClient(ElasticsearchProperties elasticsearchProperties) { HttpHost[] esHosts = elasticsearchProperties.getHosts().stream().filter(StringUtils::isNotBlank).map(it -> { String[] split = it.split(":"); return new HttpHost(split[0], Integer.parseInt(split[1]), elasticsearchProperties.getScheme()); }).toArray(HttpHost[]::new); final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(elasticsearchProperties.getUsername(), elasticsearchProperties.getPassword())); RestClientBuilder restClientBuilder = RestClient.builder(esHosts); // 连接延时配置 restClientBuilder.setRequestConfigCallback(requestConfigBuilder -> { requestConfigBuilder.setConnectTimeout(elasticsearchProperties.getConnectTimeOut()); requestConfigBuilder.setSocketTimeout(elasticsearchProperties.getSocketTimeOut()); requestConfigBuilder.setConnectionRequestTimeout(elasticsearchProperties.getConnectionRequestTimeOut()); return requestConfigBuilder; }); // HttpClient 连接数配置 restClientBuilder.setHttpClientConfigCallback(httpClientBuilder -> { httpClientBuilder.setMaxConnTotal(elasticsearchProperties.getMaxConnectNum()); httpClientBuilder.setMaxConnPerRoute(elasticsearchProperties.getMaxConnectNumPerRoute()); return httpClientBuilder; }); // 设置keepalive时间 restClientBuilder.setHttpClientConfigCallback(requestConfig -> requestConfig.setKeepAliveStrategy((response, context) -> Duration.ofMinutes(3).toMillis()) ); // 忽略HTTPS方式链接,SSL证书、主机名验证器 restClientBuilder.setHttpClientConfigCallback(httpAsyncClientBuilder -> { httpAsyncClientBuilder.disableAuthCaching(); httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider); try { // 创建一个信任所有证书的 TrustStrategy 策略 TrustStrategy acceptTrustStrategy = (chain, authType) -> true; // 使用 SSLContextBuilder 创建 SSLContext SSLContext sslContext = SSLContextBuilder.create().loadTrustMaterial(null, acceptTrustStrategy).build(); httpAsyncClientBuilder.setSSLContext(sslContext); } catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException e) { e.printStackTrace(); } // 忽略主机名验证 httpAsyncClientBuilder.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE); return httpAsyncClientBuilder; }); RestClient restClient = restClientBuilder.build(); // 使用Jackson映射器创建传输层 ElasticsearchTransport transport = new RestClientTransport( restClient, new JacksonJsonpMapper() ); ElasticsearchClient client = new ElasticsearchClient(transport); return client; } }四、ES相关字段
五、ES半径查询
具体查询对象,可自行定义,本方法只提供思路,莫直接粘贴使用
@Resource private ElasticsearchClient esClient; /** * 功能描述: 根据经纬度判断十米内是否有poi数据 * * @Param: [request] * @Author: meng * @Date: 2024/6/6 19:57 */ private PoiDTO getPoiNear(PoiRequest request) { if (Objects.isNull(request.getLongitude()) && Objects.isNull(request.getLatitude())) { return null; } // 中心点查询 GeoLocation geoLocation = new GeoLocation.Builder().latlon( l -> l.lon(request.getLongitude().doubleValue()).lat(request.getLatitude().doubleValue())).build(); GeoDistanceQuery geoDistanceQuery = GeoDistanceQuery.of( geoDis -> geoDis.field(PoiIndexConstant.LOCATION).location(geoLocation) .distance(PoiIndexConstant.DISTANCE).distanceType(GeoDistanceType.Arc)); // 排序 List sorts = new ArrayList(); // 距离排序 米 GeoDistanceSort geoDistanceSort = GeoDistanceSort.of( geoDis -> geoDis.field(PoiIndexConstant.LOCATION).location(geoLocation).order(SortOrder.Asc) .unit(DistanceUnit.Meters)); SortOptions sortOptions = SortOptions.of(sort -> sort.geoDistance(geoDistanceSort)); sorts.add(sortOptions); SearchRequest.Builder searchRequestBuilder = new SearchRequest.Builder(); searchRequestBuilder.index(PoiIndexConstant.INDEX_READ) .query(query -> query.bool(builder -> builder.filter(f -> f.geoDistance(geoDistanceQuery)))).sort(sorts) .size(CommonConstant.DEFAULT_NUM); // ES查询 SearchRequest searchRequest = searchRequestBuilder.build(); log.info("getPoiNear query:{}", searchRequest.toString()); try { SearchResponse searchResponse = esClient.search(searchRequest, PoiIndex.class); // 未查到数据 if (Objects.nonNull(searchResponse.hits().total()) && searchResponse.hits().total().value() == 0) { return null; } for (Hit hit : searchResponse.hits().hits()) { if (ObjectUtil.isNotNull(hit.source())) { PoiIndex poiIndex = BeanUtil.copyProperties(hit.source(), PoiIndex.class); return BeanUtil.copyProperties(poiIndex, PoiDTO.class); } } } catch (Exception e) { log.error("es searchRequest Exception:", e); throw new ServiceException("searchRequest Exception"); } return null; }
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

