您的位置:首页 > 其它

ES Geo(地理位置)相关 (持续更新)

2017-01-05 14:32 1616 查看

Geo datatype

https://www.elastic.co/guide/en/elasticsearch/reference/2.1/geo-point.html

1 Geo-point

ES geo_point类型字段,地球表面可以用经纬度描述的一个点。

其可以用来计算两个坐标间的距离,还可以判断一个坐标是否在一个区域中,或在聚合中。

类型,不能被动态映射 (dynamic mapping)自动检测,需显式声明。

可接受基于”经纬度(latitude-longitude pairs)”查询,可适用场景:

查找geo-points,

within a bounding box (Geo Bounding Box Query)

"filter": {
"geo_bounding_box": {//在特定方框内查询
"pin.location": {
"top_left": {"lat": 40.73,"lon": -74.1},//左上
"bottom_right": {"lat": 40.01,"lon": -71.12}//右下
}
}
}


certain distance of a central point(Geo Distance Query)

"filter" : {
"geo_distance" : {//...
"distance" : "200km",//距离
"pin.location" : {"lat" : 40, "lon" : -70 } }//距离特定点的周边200km
}


within a polygon(多边)(Geo Polygon Query)

"filter" : {
"geo_polygon" : {//在多边形内的求点
"person.location" : {
"points" : [
{"lat" : 40, "lon" : -70},
{"lat" : 30, "lon" : -80},
{"lat" : 20, "lon" : -90}
]
}
}
}


within a geohash cell(Geohash Cell Query)

Geohashes,一种将经纬度坐标( lat/lon )编码成字符串的方式。初衷是为了让地理位置在 url 上呈现形式更友好,但现在 geohashes 已经变成一种在数据库中有效索引地理坐标点、形状的方式。

Geohashes 把整个世界分为 32 个单元的格子 —— 4 行 8 列 —— 每一个格子都用一个字母或者数字标识。每一个单元还可以进一步被分解成新的 32 个单元,…,可不断重复下去。如
gcp 覆盖了伦敦的大部分和部分南英格兰, gcpuuz94k 是白金汉宫的入口,精确到约 5 米


geohash 的长度越长精度越高。如果两个 geohashes 有共同前缀表示挨得很近。共同的前缀越长,距离就越近。

两个刚好相邻的位置,可能会有完全不同的 geohash 。在相邻的单元里,而不是同一单元。

Geohash 单元查询(geohash_cell),把经纬度坐标位置根据指定精度转换成一个 geohash ,然后查找所有包含这个 geohash 的位置——非常高效的查询。

"filter": {
"geohash_cell": {//为效率,不为精度而生
"location": {
"lat":  40.718, "lon": -73.983
},
"neighbors": true,//相邻单元也包含
"precision": "2km" //或6 , 不能高于映射时geohash_precision的值---->geohash prefix length
}
}


可能不会返回 2km 内所有的点。 geohash 仅是个矩形,而指定的点可能位于这个矩形中的任何位置。有可能这个点刚好落在了 geohash 单元的边缘附近,但过滤器会排除那些落在相邻单元的点。为了修复可以通过设置 neighbors参数为 true。

注意:将 precision 参数设置为一个距离可能会有误导性。 2km 的 precision 会被转换成长度为 6 的 geohash 【距离<==>长度】。实际上它的尺寸是约 1.2km x 0.6km。你可能会发现明确的设置长度为 5 或 6 会更容易理解。Instead of setting a geohash length directly it is also possible to define the precision as distance : “precision”: “50m”

相比 geo_bounding_box 查询,它支持一个字段中有多个坐标位置的情况。

To get this filter work all prefixes of a geohash need to be indexed.

{
"mappings" : {
"location": {
"properties": {
"pin": {
"type": "geo_point",
"geohash": true,// 默认false
"geohash_prefix": true,// 默认false
"geohash_precision": 10 // max length geohash
}
}
}
}
}


to aggregate docs by… from a central point

by geographically(GeoHash grid Agg)

Geohash 网格聚合。通过一个查询返回的结果数量对在地图上单独的显示每一个位置点可能太多。 geohash_grid 按照定义的精度计算每一个点的 geohash 值而将附近的位置聚合在一起。

结果是一个网格——一个单元格表示一个可以显示在地图上的 geohash 。通过改变 geohash 的精度,你可以按国家或者城市街区来概括全世界。

聚合是稀疏的——它仅返回那些含有文档的单元。 如果 geohashes 太精确,将产生太多的 buckets,它将默认返回那些包含了大量文档、最密集的10000个单元。 然而,为了计算哪些是最密集的 Top10000 ,它还是需要产生 所有 的 buckets 。可以通过以下方式来控制 buckets 的产生数量,避免内存创建太多bucket

使用
geo_bounding_box
限制结果。

为边界大小选择适当的
precision
(精度)

GET /attractions/restaurant/_search
{
"size" : 0,
"query": {
"constant_score": {
"filter": {
"geo_bounding_box": {//边界框(geo_bounding_box)限制范围
"location": {
"top_left": { "lat":  40.8, "lon": -74.1},
"bottom_right": { "lat":  40.4, "lon": -73.7 }
}
}
}
}
},
"aggs": {
"new_york": {
"geohash_grid": {
"field":     "location",
"precision": 5//精度5,大约5km*5km
}
}
}
}
结果:
"aggregations": {
"new_york": {
"buckets": [
{
"key": "dr5rs",//每个bucket包含作为key的geohash值
"doc_count": 2
},
{
"key": "dr5re",
"doc_count": 1
}
]
}
}


by distance(Geo Distance Agg)

对一些搜索非常有用,例如找到距离 1km 以内的点。

"aggs": {
"per_ring": {
"geo_distance": {
"field":    "location",
"unit":     "km",
"origin": {
"lat":  40.712, "lon": -73.988
},
"ranges": [
{ "from": 0, "to": 1 }, //1km以内
{ "from": 1, "to": 2 } // 1~2km内的
]
}
}
}


结果:

"aggregations": {
"per_ring": {
"buckets": [
{
"key":       "*-1.0",
"from":      0,
"to":        1,
"doc_count": 1  //1km以内的数量
},
{
"key":       "1.0-2.0",
"from":      1,
"to":        2,
"doc_count": 1  //1~2km内数量
}
]
}
}


to integerate distance into a doc’s relevance score.

to sort docs by distance.

2 Geo-Shape

Geo查询

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: