做搜索定位这行七年了,我见过太多人拿着elasticsearch5 geo搞不定经纬度精度,最后急得跳脚。别急,这篇纯干货直接告诉你怎么把精度从几百米提升到几米,专治各种不服。看完这篇,你不仅能解决定位漂移,还能少加两个班。
先说个真事儿。上周有个兄弟找我,说他们系统里查附近的餐厅,明明用户就在楼下,结果搜出来的是隔壁区的店。我一看日志,好家伙,经纬度存的是字符串!这在es5里简直就是自杀行为。es5对geo_point的支持虽然比es2好多了,但如果你数据源没处理好,它就是个摆设。咱们得先搞清楚,为什么你的elasticsearch5 geo查询会拉胯?
第一,数据格式必须对。别整那些花里胡哨的,直接存成对象或者数组。比如{"lat": 39.9, "lon": 116.4},或者[116.4, 39.9]。千万别存成"39.9,116.4"这种字符串,除非你想让es把它当普通文本处理,那查询速度能慢到你怀疑人生。我见过不少坑,就是因为前端传参没转义,后端直接塞进去了,结果查不出任何结果,还以为是代码bug。
第二,映射类型别选错。在创建索引的时候,字段类型一定要选geo_point。如果你选了text或者keyword,那基本就没戏了。es5里有个坑,就是默认的分词器可能会把你的经纬度拆开,导致索引混乱。所以,建表的时候,老老实实写死类型,别偷懒。
第三,查询方式得讲究。很多人喜欢用match查询,这在geo场景下是大忌。你得用geo_distance或者geo_bounding_box。特别是geo_distance,它能算出你离目标点有多远。但是,这里有个隐藏的大坑:距离单位。默认是米,但如果你没指定,或者单位搞混了,算出来的距离可能差之千里。比如你以为是公里,结果是米,那结果肯定不对。
再说说价格。很多小白觉得用es要买昂贵的商业版,其实es5的开源版完全够用。除非你数据量达到PB级,否则社区版加上合理的集群配置,跑几个亿的geo数据也不是问题。我之前的一个客户,用了三台服务器,跑着elasticsearch5 geo查询,响应时间控制在200毫秒以内,成本不到两万块。这性价比,不比那些动不动就几十万的商业软件香吗?
避坑指南来了。第一,别在查询时动态改变映射。es5虽然支持动态映射,但geo字段一旦创建,类型就不能改。想改?删索引重建。第二,注意时区问题。虽然geo本身不涉及时区,但如果你关联的时间字段没处理好,排序可能会乱。第三,别忽视性能。geo查询在数据量大时,CPU消耗很高。记得加索引,虽然es5的geo_point会自动创建doc_values,但合理的设计分片还是必要的。
最后总结一下,elasticsearch5 geo定位不准,多半是数据格式和查询方式没搞对。别瞎折腾,先检查数据,再检查映射,最后检查查询语句。按我说的做,保证你的定位精度蹭蹭往上涨。要是还搞不定,那可能是你的硬件太拉胯,该升级服务器了。
本文关键词:elasticsearch5 geo