7.2 地理数据:带坐标的文档如何旅行


文档摘要

7.2 地理数据:带坐标的文档如何旅行 本节摘要:geopoint 类型给文档装上经纬度,距离检索回答"三公里内有哪些网点",边界框检索回答"地图这块区域里有什么";地理聚合再按距离或网格分桶。本节讲 geopoint 的录入形态、两类检索写法与聚合姿势,末尾巡礼反向搜索与跨集群检索,把高级特性的地图边界画完整。 带坐标的旅程 坐标字段的两种录入形态 门店文档带一个 geopoint 字段,录入形态灵活: 经度在前是字符串与数组形态的铁律(地理行业惯例),对象形态最不易出错——团队协作时建议统一用对象。geopoint 底层把坐标编码成可区间比较的数值(地球投影成可排序的一维编码),距离计算与范围裁剪都靠它高效完成。

7.2 地理数据:带坐标的文档如何旅行

本节摘要:geo_point 类型给文档装上经纬度,距离检索回答"三公里内有哪些网点",边界框检索回答"地图这块区域里有什么";地理聚合再按距离或网格分桶。本节讲 geo_point 的录入形态、两类检索写法与聚合姿势,末尾巡礼反向搜索与跨集群检索,把高级特性的地图边界画完整。

带坐标的旅程

坐标字段的两种录入形态

门店文档带一个 geo_point 字段,录入形态灵活:

PUT branches/_doc/bj-001 { "name": "北苑服务网点", "location": { "lat": 39.9847, "lon": 116.3075 } }
以下形态等价 任选其一保持团队统一: 字符串形态 "116.3075,39.9847" 注意经度在前 数组形态 [116.3075, 39.9847] 同样经度在前 对象形态 lat lon 各自命名 最不易错

经度在前是字符串与数组形态的铁律(地理行业惯例),对象形态最不易出错——团队协作时建议统一用对象。geo_point 底层把坐标编码成可区间比较的数值(地球投影成可排序的一维编码),距离计算与范围裁剪都靠它高效完成。再复杂的形态(多边形、线路)属于 geo_shape 类型的领地,按需另学,网点场景 geo_point 足够。

两种问法:距离与边界

问法一:三公里内有什么。

GET branches/_search { "query": { "bool": { "must": { "match": { "name": "服务网点" } }, "filter": { "geo_distance": { "distance": "3km", "location": { "lat": 39.9912, "lon": 116.3217 } } } } }, "sort": [ { "_geo_distance": { "location": { "lat": 39.9912, "lon": 116.3217 }, "order": "asc", "unit": "km" } } ] }

geo_distance 放 filter 里(距离是硬条件不是相关性),排序用 _geo_distance 按实际距离升序——响应里每条命中会带一个距离值,前端直接显示"距您 1.2 公里"。

问法二:地图这个框里有什么。

GET branches/_search { "query": { "geo_bounding_box": { "location": { "top_left": { "lat": 40.0100, "lon": 116.2800 }, "bottom_right": { "lat": 39.9700, "lon": 116.3500 } } } } }

地图产品拖动视野时,前端把可视范围换成左上右下两个角点发来即可。两种问法组合上 bool 与其他条件,"框内且营业中且评分高于四"这类复合地理需求照样翻译。

地理检索与聚合的坐标系

地理检索与聚合的坐标系

地理聚合

GET branches/_search { "size": 0, "aggs": { "by_ring": { "geo_distance": { "field": "location", "origin": { "lat": 39.9912, "lon": 116.3217 }, "ranges": [ { "to": 1000 }, { "from": 1000, "to": 3000 }, { "from": 3000, "to": 10000 } ] } } } }

geo_distance 聚合按距离环带分桶,"一公里内五家、一到三公里十四家"的覆盖报告一步到位;geohash_grid 聚合按地图网格分格,是热力图与地图打点的数据源,精度参数控制格子大小。第 6 章的嵌套语法在这里原样适用——环带里再嵌服务类型桶,报表立起第二个维度。

高级特性巡礼:两个值得记住的入口

本章是高级特性的家,除地理之外再记两个入口,不展开但留路标。反向搜索(percolator):普通流程是"存文档、发查询",它反着来——存查询、发文档,回答"这条新文档会被哪些查询命中"。告警订阅正是此形态:把告警条件存成查询,日志流逐条过堂,命中即报警。跨集群检索:把远端集群登记为友邻,一条请求同时搜本地与远端,并购整合、多地域统一搜索的场景免去了数据搬运。两者加上第 8 章要讲的冻结索引(冷数据搜索),构成高级特性的地图片区——遇到对应场景,知道往哪个门里走。

一次"附近网点"功能的落地

背景:App 要上"附近的服务网点",产品要求按距离排序、显示距离、三公里内优先展示营业中的。操作:映射建 geo_point 对象形态;查询 filter 里 geo_distance 三公里、must 里 match 营业关键词,排序 _geo_distance 升序;分页沿用 5.3 的浅翻页(结果页场景)。结果:城市热点区域毫秒级响应;乡镇低密度区域偶发"三公里内为空",产品补充了兜底逻辑(无结果时扩大到十公里)。解读:地理查询的两问一聚覆盖了这类功能的全部需求面;"无结果"的兜底是产品侧的地理常识,不是引擎缺陷。变式:要做热力图时把查询换成 geohash_grid 聚合;要按行政区分统计时,写入端补一个区域编码字段(geo_point 反查行政区引擎不做,预计算是正解)。

⚠️ 常见坑:字符串形态经纬度写反(纬度在前),所有距离计算悄悄错位——点是能查出来的,距离全不对,最隐蔽的一类错。统一对象形态加一条录入校验,比事后排错省一下午。

💡 关键直觉:geo_point 解决"点与点、点与框"的关系;行政区、多边形这类"归属"关系应该在写入端预计算成普通字段。引擎擅长算距离,不擅长猜归属。

坐标归档

  • geo_point 两种录入形态,对象形态最不易错;经度在前仅限字符串与数组形态。
  • 距离检索配 _geo_distance 排序,边界框检索服务地图视野,两者都放 filter。
  • geo_distance 桶分环带,geohash_grid 桶出热力图,嵌套语法与第 6 章一致。
  • 反向搜索适合告警订阅,跨集群检索适合多地域统一搜索,遇场景记得到此取匙。

考核要点补充

  • 两种问法的组合:距离圈与边界框都能嵌进 bool 的 filter,与营业状态、评分等业务条件并列成复合查询。
  • 无结果的兜底:低密度区域"扩大半径再查一次"应由产品层实现,引擎只忠实执行当前条件,别把兜底逻辑写进引擎侧。

复杂形态归位。下一章是旅程最壮阔的一段:分片远行——集群解剖、路由再平衡、近实时幕后与备份护航。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U