CosmosDB ST_DISTANCE查询未按预期运行,查询1KM半径内用户返回超范围结果
问题根因与解决方法
出现这个问题绝大多数情况是以下两个原因导致的,你可以按顺序排查:
- 经纬度顺序不符合GeoJSON规范
GeoJSON要求Point类型的coordinates字段必须遵循[经度, 纬度]的排序,这和很多开发者习惯的纬度在前、经度在后的书写习惯正好相反。你查询语句里传入的坐标、以及存储在用户location字段里的坐标如果顺序写反,ST_DISTANCE计算出的结果会完全失真,就会出现距离远超1km的结果被误判为符合条件的情况。
你例子里的两个点坐标数值差接近1度,对应实际距离超过上百公里,显然是顺序写反后计算出来的错误值刚好小于1000导致的。 - 容器地理空间配置类型错误
CosmosDB容器支持两种地理空间配置:- 默认的
Geography类型:ST_DISTANCE返回值单位为米,适合你这种计算地表两点距离的场景 Geometry类型:ST_DISTANCE返回值为坐标参考系的平面单位,不会按球面距离计算,单位也不是米,用<1000的判断逻辑自然不符合预期
- 默认的
排查步骤
- 先调整坐标顺序重新测试,比如你要查询的中心点纬度是-25.131999881000644、经度是-46.84260389576425,那正确的查询语句应该写成:
SELECT * FROM user u WHERE ST_DISTANCE(u.location, {'type': 'Point', 'coordinates':[-46.84260389576425, -25.131999881000644]}) < 1000
注意同步确认你存储的用户location坐标也遵循[经度, 纬度]的顺序。
2. 若调整顺序后问题依然存在,到CosmosDB容器的设置页确认地理空间配置为Geography类型,若当前为Geometry类型可以修改配置后重新导入数据,或调整阈值适配平面坐标单位。
3. 可以单独执行距离计算语句验证计算结果是否符合预期:
SELECT ST_DISTANCE( {'type': 'Point', 'coordinates':[-46.84260389576425, -25.131999881000644]}, {'type': 'Point', 'coordinates':[-45.84260389576425, -24.171999881000644]} ) AS actual_distance
如果返回的数值和你用第三方经纬度距离工具计算出的实际距离一致,就说明配置和坐标顺序都已经正确。
内容的提问来源于stack exchange,提问作者Henrique Š.
相关产品推荐
相关产品推荐

