案例背景
一个酒店o2o的app,根据用户指定的位置,找到周围的符合条件的酒店.
geo_point地理位置数据类型
geo_point,就是一个地理位置坐标点,记录了经度和纬度,通过经纬度,就可以定位地球上的位置
创建索引
1 | PUT /my_index |
field的类型设置为geo_point
写入geo_point的三种方法
第一种1
2
3
4
5
6
7
8PUT /my_index/my_type/1
{
"text": "Geo-point as an object",
"location": {
"lat": 41.12,
"lon": -71.34
}
}
- latitude(lat): 纬度
- longitude(lon): 经度
第二种1
2
3
4
5PUT my_index/my_type/2
{
"text": "Geo-point as a string",
"location": "41.12,-71.34"
}
第三种1
2
3
4
5PUT my_index/my_type/4
{
"text": "Geo-point as an array",
"location": [ -71.34, 41.12 ]
}
后面两种不推荐使用
搜索
geo_bounding_box查询
geo_bounding_box查询: 查询某个矩形的地理位置范围内的坐标点
看一下搜索请求:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17GET /my_index/my_type/_search
{
"query": {
"geo_bounding_box":{
"location":{
"top_left":{
"lat":42,
"lon":-72
},
"bottom_right":{
"lat":40,
"lon":-74
}
}
}
}
}
返回值:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51{
"took": 17,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 3,
"max_score": 1,
"hits": [
{
"_index": "my_index",
"_type": "my_type",
"_id": "2",
"_score": 1,
"_source": {
"text": "Geo-point as a string",
"location": "41.12,-71.34"
}
},
{
"_index": "my_index",
"_type": "my_type",
"_id": "4",
"_score": 1,
"_source": {
"text": "Geo-point as an array",
"location": [
-71.34,
41.12
]
}
},
{
"_index": "my_index",
"_type": "my_type",
"_id": "1",
"_score": 1,
"_source": {
"text": "Geo-point as an object",
"location": {
"lat": 41.12,
"lon": -71.34
}
}
}
]
}
}
搜索的时候指定了一个top_left,和一个bottom_right
如上图,以top_left,和一个bottom_right 成一个矩形,然后这个矩形之内的坐标对应的数据都可以被搜索出来
geo_polygon查询
geo_polygon查询:以多个坐标组成一个多边形来查询1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32GET /my_index/my_type/_search
{
"query": {
"bool": {
"must": [
{
"match_all": {}
}
],
"filter": {
"geo_polygon": {
"location": {
"points": [
{
"lat": 40.73,
"lon": -74.1
},
{
"lat" : 40.01,
"lon" : -71.12
},
{
"lat" : 50.56,
"lon" : -90.58
}
]
}
}
}
}
}
}
跟上面的矩形搜索是类似的,只不过这里是以多个坐标组成的多边形去搜索
距离查询
比如说要查询距离自己200km以内的酒店, 我们自己的坐标是知道的 app都可以获取的到
搜索1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21GET /my_index/my_type/_search
{
"query": {
"bool": {
"must": [
{
"match_all": {}
}
],
"filter": {
"geo_distance": {
"distance": "200km",
"location": {
"lat": 40.73,
"lon": -74.1
}
}
}
}
}
}
location里面的经纬度就是我们自己的坐标,然后distance,设置查询距离
聚合分析
需求:统计距离我当前位置的几个范围内的酒店数量, 比如我0-100m有几个酒店,100-300m有几个,300以上的有几个
请求:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28GET /my_index/my_type/_search
{
"size": 0,
"aggs": {
"agg_by_distance_range": {
"geo_distance": {
"field": "location",
"origin": {
"lat": 52.376,
"lon": 4.894
},
"unit": "mi",
"ranges": [
{
"to": 100
},
{
"from": 100,
"to": 300
},
{
"from": 300
}
]
}
}
}
}
返回值:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37{
"took": 13,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 3,
"max_score": 0,
"hits": []
},
"aggregations": {
"agg_by_distance_range": {
"buckets": [
{
"key": "*-100.0",
"from": 0,
"to": 100,
"doc_count": 0
},
{
"key": "100.0-300.0",
"from": 100,
"to": 300,
"doc_count": 0
},
{
"key": "300.0-*",
"from": 300,
"doc_count": 3
}
]
}
}
}
请求中的几个参数
- unit:单位,可以是mi 也可以是km
- origin: 自己当前的坐标
- ranges: 要统计的几个区间