7.4 Geospatial 数据处理 Elasticsearch 高级特性:7.4 Geospatial 数据处理 7.4.1 Geospatial 数据类型 Elasticsearch 支持两种主要的 geospatial 数据类型: : 用于存储经纬度坐标。 : 用于存储更复杂的地理形状,如多边形、线段等。 7.4.1.1 类型用于存储单个地理位置的经纬度坐标。你可以使用以下几种格式来表示坐标: 字符串: (例如: ) 对象: (例如: ) 数组: (例如: ) 推荐使用对象格式,因为它更易于理解和维护。 7.4.1.2 类型用于存储更复杂的地理形状。它支持 GeoJSON 格式,这是一种用于表示各种地理要素的标准格式。
Elasticsearch 支持两种主要的 geospatial 数据类型:
geo_point: 用于存储经纬度坐标。
geo_shape: 用于存储更复杂的地理形状,如多边形、线段等。
geo_pointgeo_point 类型用于存储单个地理位置的经纬度坐标。你可以使用以下几种格式来表示坐标:
字符串: "latitude,longitude" (例如: "40.7128,-74.0060")
对象: {"lat": latitude, "lon": longitude} (例如: {"lat": 40.7128, "lon": -74.0060})
数组: [longitude, latitude] (例如: [-74.0060, 40.7128])
推荐使用对象格式,因为它更易于理解和维护。
geo_shapegeo_shape 类型用于存储更复杂的地理形状。它支持 GeoJSON 格式,这是一种用于表示各种地理要素的标准格式。你可以使用以下 GeoJSON 类型:
Point: 单个点
LineString: 一条线段
Polygon: 多边形
MultiPoint: 多个点
MultiLineString: 多条线段
MultiPolygon: 多个多边形
GeometryCollection: 包含多个几何对象的集合
在使用 geospatial 数据之前,你需要在 Elasticsearch 中创建索引并定义映射。映射指定了每个字段的数据类型和索引方式。
geo_point 映射示例PUT /my_index { "mappings": { "properties": { "location": { "type": "geo_point" }, "name": { "type": "text" } } } }
这个映射定义了一个名为 location 的字段,其类型为 geo_point。
geo_shape 映射示例PUT /my_index { "mappings": { "properties": { "area": { "type": "geo_shape", "tree": "quadtree", "precision": "1km" }, "name": { "type": "text" } } } }
这个映射定义了一个名为 area 的字段,其类型为 geo_shape。tree 参数指定了用于索引形状的树结构(quadtree 或 geohash),precision 参数指定了树的精度。
关于 tree 和 precision 的选择:
quadtree: 适合于更精确的形状匹配,通常用于较小的区域。
geohash: 适合于较大区域的粗略匹配,性能更好。
precision: 控制树的精度。较小的精度值(如 "1m")会产生更精确的结果,但索引和搜索的成本更高。较大的精度值(如 "1km")会降低精度,但提高性能。
Elasticsearch 也可以动态识别geo_point字段,通过设置index.mapper.dynamic为true即可。
PUT /my_index { "settings": { "index.mapper.dynamic": true } }
创建索引和映射后,你可以开始索引包含 geospatial 数据的文档。
geo_point 索引示例PUT /my_index/_doc/1 { "name": "Empire State Building", "location": { "lat": 40.7484, "lon": -73.9857 } }
geo_shape 索引示例PUT /my_index/_doc/2 { "name": "Central Park", "area": { "type": "Polygon", "coordinates": [ [ [-73.982, 40.785], [-73.958, 40.796], [-73.949, 40.768], [-73.973, 40.757], [-73.982, 40.785] ] ] } }
Elasticsearch 提供了多种 geospatial 查询,允许你根据位置信息来搜索文档。
geo_distance 查询geo_distance 查询查找在指定点一定距离内的文档。
GET /my_index/_search { "query": { "geo_distance": { "distance": "1km", "location": { "lat": 40.75, "lon": -73.99 } } } }
这个查询查找距离坐标 (40.75, -73.99) 1 公里内的所有文档。
geo_bounding_box 查询geo_bounding_box 查询查找位于指定矩形框内的文档。
GET /my_index/_search { "query": { "geo_bounding_box": { "location": { "top_left": { "lat": 40.8, "lon": -74.0 }, "bottom_right": { "lat": 40.7, "lon": -73.9 } } } } }
这个查询查找位于由左上角坐标 (40.8, -74.0) 和右下角坐标 (40.7, -73.9) 定义的矩形框内的所有文档。
geo_polygon 查询geo_polygon 查询查找位于指定多边形内的文档。
GET /my_index/_search { "query": { "geo_polygon": { "location": { "points": [ { "lat": 40.7, "lon": -74.0 }, { "lat": 40.8, "lon": -73.9 }, { "lat": 40.75, "lon": -73.8 } ] } } } }
这个查询查找位于由三个点定义的多边形内的所有文档。
geo_shape 查询geo_shape 查询允许你根据 geo_shape 字段之间的关系来搜索文档。它支持以下关系类型:
intersects: 形状相交
disjoint: 形状不相交
within: 形状完全在另一个形状内
contains: 形状完全包含另一个形状
GET /my_index/_search { "query": { "geo_shape": { "area": { "relation": "intersects", "shape": { "type": "Polygon", "coordinates": [ [ [-74.1, 40.7], [-73.9, 40.7], [-73.9, 40.8], [-74.1, 40.8], [-74.1, 40.7] ] ] } } } } }
这个查询查找 area 字段与指定多边形相交的所有文档。
Elasticsearch 提供了 geospatial 聚合,允许你分析地理位置数据。
geo_distance 聚合geo_distance 聚合将文档分组到距离指定点的不同距离范围内。
GET /my_index/_search { "size": 0, "aggs": { "rings": { "geo_distance": { "field": "location", "origin": { "lat": 40.75, "lon": -73.99 }, "unit": "km", "ranges": [ { "to": 1 }, { "from": 1, "to": 5 }, { "from": 5 } ] } } } }
这个聚合将文档分组到距离坐标 (40.75, -73.99) 的 0-1 公里、1-5 公里和 5 公里以上的范围内。
geohash_grid 聚合geohash_grid 聚合将文档分组到 geohash 网格单元中。
GET /my_index/_search { "size": 0, "aggs": { "grid": { "geohash_grid": { "field": "location", "precision": 5 } } } }
这个聚合将文档分组到精度为 5 的 geohash 网格单元中。
假设你有一个包含咖啡馆信息的索引,每个咖啡馆都有一个 location 字段,类型为 geo_point。你可以使用以下查询来查找距离用户位置 500 米内的所有咖啡馆:
GET /coffee_shops/_search { "query": { "geo_distance": { "distance": "500m", "location": { "lat": 34.0522, "lon": -118.2437 } } } }
Elasticsearch 的 geospatial 功能为处理地理位置数据提供了强大的工具。你可以使用 geo_point 和 geo_shape 数据类型来存储位置信息,使用各种 geospatial 查询来搜索文档,并使用 geospatial 聚合来分析数据。通过结合这些功能,你可以构建各种基于位置的应用,例如查找附近的地点、分析地理区域内的事件等等。
希望这篇文章能够帮助你更好地理解和使用 Elasticsearch 的 geospatial 数据处理能力。