案例背景
比如我们有很多的4s店,然后呢给了用户一个app,在某个地方的时候,可以根据当前的地理位置搜索一下,自己附近的4s店
数据准备
添加一个地理位置的field,手动设置mapping映射,然后添加一条测试数据1
2
3
4
5
6
7
8
9
10
11
12POST /car_shop/_mapping/shops
{
"properties": {
"pin": {
"properties": {
"location": {
"type": "geo_point"
}
}
}
}
}
1 | PUT /car_shop/shops/1 |
依赖引入
maven中引入基于地理位置查询的依赖1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<dependency>
<groupId>org.locationtech.spatial4j</groupId>
<artifactId>spatial4j</artifactId>
<version>0.6</version>
</dependency>
<dependency>
<groupId>com.vividsolutions</groupId>
<artifactId>jts</artifactId>
<version>1.13</version>
<exclusions>
<exclusion>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
</exclusion>
</exclusions>
</dependency>
矩形搜索
搜索两个坐标点,组成的一个矩形区域1
2
3
4
5
6
7
8
9
10
11
12
13
14@Test
public void getBoundingBoxQuery(){
QueryBuilder queryBuilder = QueryBuilders.geoBoundingBoxQuery("pin.location").setCorners(40.73, -74.1, 40.01, -71.12);
SearchResponse response = client.prepareSearch("car_shop")
.setTypes("shops")
.setQuery(queryBuilder)
.get();
for (SearchHit hit : response.getHits().getHits()) {
log.info("hit:{}", hit.getSourceAsString());
}
}
console:1
2
3
4
5
6
7
8
92019-01-23 16:39:39.306 [main] INFO com.demo.elasticsearch.CarShopTests - hit:{
"name": "上海至全宝马4S店",
"pin" : {
"location" : {
"lat" : 40.12,
"lon" : -71.34
}
}
}
多个坐标点区域查询
多个坐标点组成一个多边形区域1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21@Test
public void geoPolygonQuery(){
// 多个坐标点
List<GeoPoint> points = new ArrayList<>(3);
points.add(new GeoPoint(40.73, -74.1));
points.add(new GeoPoint(40.01, -71.12));
points.add(new GeoPoint(50.56, -90.58));
// 查询条件
QueryBuilder queryBuilder = QueryBuilders.geoPolygonQuery("pin.location", points);
SearchResponse response = client.prepareSearch("car_shop")
.setTypes("shops")
.setQuery(queryBuilder)
.get();
for (SearchHit hit : response.getHits().getHits()) {
log.info("hit:{}", hit.getSourceAsString());
}
}
console:1
2
3
4
5
6
7
8
92019-01-23 16:49:05.885 [main] INFO com.demo.elasticsearch.CarShopTests - hit:{
"name": "上海至全宝马4S店",
"pin" : {
"location" : {
"lat" : 40.12,
"lon" : -71.34
}
}
}
根据当前坐标的范围查询
以某一坐标为基准,查询距离该坐标2km以内的数据1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17@Test
public void geoDistanceQuery(){
// 查询条件
QueryBuilder queryBuilder = QueryBuilders.geoDistanceQuery("pin.location")
.point(40, -70)
.distance(200, DistanceUnit.KILOMETERS);
SearchResponse response = client.prepareSearch("car_shop")
.setTypes("shops")
.setQuery(queryBuilder)
.get();
for (SearchHit hit : response.getHits().getHits()) {
log.info("hit:{}", hit.getSourceAsString());
}
}
console:1
2
3
4
5
6
7
8
92019-01-23 16:55:23.224 [main] INFO com.demo.elasticsearch.CarShopTests - hit:{
"name": "上海至全宝马4S店",
"pin" : {
"location" : {
"lat" : 40.12,
"lon" : -71.34
}
}
}
最后
以上的java Api的代码,都放在了github,传送门