Java High Level REST Client 使用地理位置查询
Java High Level REST Client 使用地理位置查询
一、需求
在前一篇文章中,我们学会了geo_point的使用,此处使用地理位置查询并使用java语言实现一下。
功能:
1、实现查询、过滤。
2、实现聚合。
3、实现排序。
4、实现后置过滤。
二、对应的query语句
GET geo_index/_search
{
"from": 0,
"size": 10,
"timeout": "20s",
"query": {
"bool": {
"must": [
{
"match_all": {
"boost": 1.0
}
}
],
"filter": [
{
"geo_distance": {
"location": [
121.462311,
31.256224
],
"distance": 3000.0,
"distance_type": "arc",
"validation_method": "STRICT",
"ignore_unmapped": false,
"boost": 1.0,
"_name": "optional_name"
}
}
],
"adjust_pure_negative": true,
"boost": 1.0
}
},
"post_filter": {
"geo_distance": {
"location": [
121.462311,
31.256224
],
"distance": 1000.0,
"distance_type": "arc",
"validation_method": "STRICT",
"ignore_unmapped": false,
"boost": 1.0
}
},
"sort": [
{
"_geo_distance": {
"location": [
{
"lat": 31.256224,
"lon": 121.462311
}
],
"unit": "m",
"distance_type": "arc",
"order": "desc",
"validation_method": "STRICT",
"ignore_unmapped": false
}
}
],
"aggregations": {
"distanceAgg": {
"geo_distance": {
"field": "location",
"origin": {
"lat": 31.256224,
"lon": 121.462311
},
"ranges": [
{
"key": "first",
"from": 0.0,
"to": 500.0
},
{
"key": "second",
"from": 500.0,
"to": 1000.0
},
{
"key": "third",
"from": 1000.0
}
],
"keyed": true,
"unit": "m",
"distance_type": "ARC"
}
}
}
}
三、对应java代码
1、引入 jar 包
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.7.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.12.0</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.14.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.1</version>
</dependency>
</dependencies>
2、创建 RestHighLevelClient
public class AbstractEsApi {
protected final RestHighLevelClient client;
public AbstractEsApi() {
client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http"),
new HttpHost("localhost", 9201, "http"),
new HttpHost("localhost", 9202, "http")
)
);
}
}
3、实现查询
1、方式一-使用api
import com.huan.study.esapi.AbstractEsApi;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.ShardSearchFailure;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.range.ParsedGeoDistance;
import org.elasticsearch.search.aggregations.bucket.range.Range;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.GeoDistanceSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.Arrays;
/**
* distance query 类型的 地理位置查询
*
* @author huan.fu 2021/4/22 - 下午4:00
*/
public class DistanceQueryApi extends AbstractEsApi {
@DisplayName("距离查询")
@Test
public void distanceQueryTest() throws IOException {
// 查询请求
SearchRequest searchRequest = new SearchRequest("geo_index");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 从索引那个开始返回数据
searchSourceBuilder.from(0);
// 查询多少条记录
searchSourceBuilder.size(10);
// 查询超时时间
searchSourceBuilder.timeout(TimeValue.timeValueSeconds(20));
// 构造查询和过滤数据
searchSourceBuilder.query(
// 构造布尔查询
QueryBuilders.boolQuery()
// 查询语句
.must(
QueryBuilders.matchAllQuery()
)
// 过滤语句
.filter(
// name 是过滤的字段
QueryBuilders.geoDistanceQuery("location")
// 在3km之内
.distance("3", DistanceUnit.KILOMETERS)
// 以那个点为中心
.point(31.256224D, 121.462311D)
.geoDistance(GeoDistance.ARC)
// 一个查询的名字,可选
.queryName("optional_name")
)
);
// 后置过滤
searchSourceBuilder.postFilter(
// name 是过滤的字段
QueryBuilders.geoDistanceQuery("location")
// 在3km之内
.distance("1", DistanceUnit.KILOMETERS)
// 以那个点为中心
.point(31.256224D, 121.462311D)
);
// 排序
searchSourceBuilder.sort(
// 不同的类型使用不同的SortBuilder
new GeoDistanceSortBuilder("location", 31.256224D, 121.462311D)
.order(SortOrder.DESC)
.unit(DistanceUnit.METERS)
.geoDistance(GeoDistance.ARC)
);
// 聚合操作
searchSourceBuilder.aggregation(
// name 聚合的名字 point 以那个点为中心开始聚合
AggregationBuilders.geoDistance("distanceAgg", new GeoPoint(31.256224D, 121.462311D))
// 字段
.field("location")
.unit(DistanceUnit.METERS)
.distanceType(GeoDistance.ARC)
.keyed(true)
// 范围
.addRange("first", 0.0D, 500D)
.addRange("second", 500D, 1000D)
.addRange("third", 1000D, Double.NEGATIVE_INFINITY)
);
searchRequest.source(searchSourceBuilder);
System.out.println("查询语句:" + searchSourceBuilder.toString());
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
System.out.println("查询结果:" + searchResponse);
RestStatus status = searchResponse.status();
System.out.println(status.getStatus());
System.out.println(searchResponse.isTerminatedEarly());
System.out.println(searchResponse.isTimedOut());
for (ShardSearchFailure shardFailure : searchResponse.getShardFailures()) {
System.out.println(shardFailure);
}
// 匹配到的结果
for (SearchHit hit : searchResponse.getHits().getHits()) {
// 数据
System.out.println(hit.getSourceAsMap());
// 排序距离
Object[] sortValues = hit.getSortValues();
System.out.println(Arrays.toString(sortValues));
System.out.println("=====");
}
// 获取聚合的结果
Aggregations aggregations = searchResponse.getAggregations();
aggregations.getAsMap().forEach((key, value) -> {
System.out.println("key:" + key);
for (Range.Bucket bucket : ((ParsedGeoDistance) value).getBuckets()) {
System.out.println("from:" + bucket.getFromAsString() + " to:" + bucket.getToAsString() + " value:" + bucket.getDocCount());
}
System.out.println("------------");
});
}
}
2、方式二-之内传入json查询串
Request request = new Request("GET", "geo_index/_search");
// 需要查询的 json 字符串
String queryJsonEntity = "{\"from\":0,\"size\":10,\"timeout\":\"20s\",\"query\":{\"bool\":{\"must\":[{\"match_all\":{\"boost\":1.0}}],\"filter\":[{\"geo_distance\":{\"location\":[121.462311,31.256224],\"distance\":3000.0,\"distance_type\":\"arc\",\"validation_method\":\"STRICT\",\"ignore_unmapped\":false,\"boost\":1.0,\"_name\":\"optional_name\"}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"post_filter\":{\"geo_distance\":{\"location\":[121.462311,31.256224],\"distance\":1000.0,\"distance_type\":\"arc\",\"validation_method\":\"STRICT\",\"ignore_unmapped\":false,\"boost\":1.0}},\"sort\":[{\"_geo_distance\":{\"location\":[{\"lat\":31.256224,\"lon\":121.462311}],\"unit\":\"m\",\"distance_type\":\"arc\",\"order\":\"desc\",\"validation_method\":\"STRICT\",\"ignore_unmapped\":false}}],\"aggregations\":{\"distanceAgg\":{\"geo_distance\":{\"field\":\"location\",\"origin\":{\"lat\":31.256224,\"lon\":121.462311},\"ranges\":[{\"key\":\"first\",\"from\":0.0,\"to\":500.0},{\"key\":\"second\",\"from\":500.0,\"to\":1000.0},{\"key\":\"third\",\"from\":1000.0}],\"keyed\":true,\"unit\":\"m\",\"distance_type\":\"ARC\"}}}}";
request.setJsonEntity(queryJsonEntity);
Response response = client.getLowLevelClient().performRequest(request);
String result = EntityUtils.toString(request.getEntity(), StandardCharsets.UTF_8);
System.out.println("响应结果: " + result);
3、输出查询语句
使用输出 SearchSourceBuilder 的结果即可。
4、输出响应结果
直接输出 SearchResponse的结果即可。
至此就完成了上方的查询。
四、注意事项
- java high level rest client 的版本最好和我们的
es的版本一致,如果不一致,那么最好要和主版本一致。 - jdk的版本最少要是
1.8的版本。 - 不推荐使用
TransportClient,这个已经过时了,在es8中将会移除。 - 输出我们自己的查询语句,直接输出
SearchSourceBuilder即可。 - 输出响应语句,直接输出
SearchResponse即可。
五、完整代码路径
六、参考文档
1、https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.12/java-rest-high-query-builders.html
2、https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.12/java-rest-high-search.html
Java High Level REST Client 使用地理位置查询的更多相关文章
- 使用Java Low Level REST Client操作elasticsearch
Java REST客户端有两种风格: Java低级别REST客户端(Java Low Level REST Client,以后都简称低级客户端算了,难得码字):Elasticsearch的官方low- ...
- Java High Level REST Client 中文API(仅供参考)
1.初始化 兼容性 Java High Level REST Client需要Java 1.8,并依赖于Elasticsearch核心项目,客户端版本与客户端开发的Elasticsearch版本相同, ...
- Elasticsearch java api操作(二)(Java High Level Rest Client)
一.说明: 一.Elasticsearch提供了两个JAVA REST Client版本: 1.java low level rest client: 低级别的rest客户端,通过http与集群交互, ...
- Elasticsearch java api操作(一)(Java Low Level Rest Client)
一.说明: 一.Elasticsearch提供了两个JAVA REST Client版本: 1.java low level rest client: 低级别的rest客户端,通过http与集群交互, ...
- 使用Java High Level REST Client操作elasticsearch
Java高级别REST客户端(The Java High Level REST Client)以后简称高级客户端,内部仍然是基于低级客户端.它提供了更多的API,接受请求对象作为参数并返回响应对象,由 ...
- Java High Level REST Client 使用示例
概述 ES 在 7.0 版本开始将废弃 TransportClient,8.0 版本开始将完全移除 TransportClient,取而代之的是 High Level REST Client,官方文档 ...
- 【ES】Java High Level REST Client 使用示例(增加修改)
ES提供了多种编程语言的链接方式,有Java API,PHP API,.NET API 官网可以详细了解 https://www.elastic.co/guide/en/elasticsearch/c ...
- SpringBoot:elasticSearch 7.2.0 Java High Level REST Client 搜索 API
Springboot整合最新版elasticSearch参考之前的文章:SpingBoot:整合ElasticSearch 7.2.0 Search API SearchRequest用于与搜索文档, ...
- SpringBoot:Java High Level REST Client 搜索 API
Springboot整合最新版elasticSearch参考之前的文章:SpingBoot:整合ElasticSearch 7.2.0 Search API SearchRequest用于与搜索文档, ...
随机推荐
- java:volatile关键字原理
volatile说明 在变量中声明后,能够在所有线程中共享改变量.并且volatile关键字能防止指令重排,即程序读取到volatile时,则不会将程序执行顺序修改. 先了解下内存模型 cpu内存模型 ...
- 百度云网速慢?普通VIP也限速?用户激励措施太套路?Pandownload被举报?这些统统没关系,我们自己搭建一个私人云盘服务器
前言 前几天醒来后,照例耍手机看新闻.在疫情如此严重的档口,一则小小的新闻引起了我内心小小的波动:Pandownload作者被举报了....心里第一件事就是可惜了我盘上的那N多个T的小电影了,&quo ...
- Webpack:打包项目报错(eslint: debugger)
打包项目需要把项目中的debugger删除,否则会报错.
- MySQL实战45讲(06--10)-笔记
目录 06 | 全局锁和表锁 :给表加个字段怎么有这么多阻碍? 全局锁 表级锁 小结 07 | 行锁功过:怎么减少行锁对性能的影响? 死锁和死锁检测 08 | 事务到底是隔离的还是不隔离的? &quo ...
- 改Jupyter Notebook的默认工作路径?
如何更改Jupyter Notebook的默认工作路径? 1.在cmd中输入命令使Jupyter产生配置文件:Jupyter_notebook_config.py jupyter notebook - ...
- 【OI】Tex Quotes——UVa 272
题目: TEX is a typesetting language developed by Donald Knuth. It takes source text together with a fe ...
- mybatis一对多联表查询的两种常见方式
1.嵌套结果查询(部分代码如下) sql语句接上: 注释:class表(c别名),student表teacher(t别名)teacher_id为class表的字段t_id为teacher表的字段,因为 ...
- PHP中操作数据库的预处理语句
今天这篇文章的内容其实也是非常基础的内容,不过在现代化的开发中,大家都使用框架,已经很少人会去自己封装或者经常写底层的数据库操作代码了.所以这回我们就来复习一下数据库中相关扩展中的预处理语句内容. 什 ...
- seo执行步骤
第一个金字塔策略这个很适用于大型网站,我想做过大型网站,特别是关键词比较多比较杂乱的站长来说,这个图太熟悉不过了,就算是没有见过,但实际操作中早就用到了这些手法.如果能把这个图领会透并实际应用,做一个 ...
- django 高级扩展-中间件-上传图片-分页-富文本-celery
""" django 高级扩展 一.静态文件 1.css,js,json,图片,字体等 2.配置setting,在最底下设置静态文件目录,写入下面代码 #配置静态文件目录 ...