Postgres使用earthdistance查询时报错function point(text, text)不存在
问题原因分析
- 你
location表的lng、lat字段是文本(text/varchar)类型,PostgreSQL内置的point()构造函数仅支持数值类型参数,不接受文本类型输入,因此触发类型不匹配报错。 - 额外注意:
earthdistance扩展的<@>运算符默认返回的距离单位是英里,你直接写<10000会得到错误的过滤范围,10公里需要先转换为对应英里数(10公里≈6.2137英里)。
解决方案步骤
- 先确认依赖扩展安装完整,
earthdistance依赖cube扩展,需要先安装cube再安装earthdistance:
CREATE EXTENSION IF NOT EXISTS cube; CREATE EXTENSION IF NOT EXISTS earthdistance;
- 对
lng和lat字段做显式数值类型转换,调整后的查询语句如下:
SELECT *, (point(lng::float8, lat::float8) <@> point(-0.1281552,51.5107975)) * 1.60934 AS distance FROM location WHERE (point(lng::float8, lat::float8) <@> point(-0.1281552,51.5107975)) < 6.2137 ORDER BY distance;
上述改动的说明:
- 加
::float8做强制类型转换,把文本类型的经纬度转成浮点数值,匹配point函数的参数要求 - 末尾乘
1.60934是把英里转换为公里,若需要米为单位可以乘1609.34;过滤条件中的6.2137就是10公里对应的英里数值。
可选优化方案
如果需要频繁执行这类地理查询,建议直接把lng、lat字段修改为数值类型,避免每次查询都做类型转换,也方便后续添加索引提升查询效率:
ALTER TABLE location ALTER COLUMN lng TYPE float8 USING lng::float8, ALTER COLUMN lat TYPE float8 USING lat::float8;
修改字段类型后,你原本的查询仅需要调整距离单位参数即可正常运行。
内容的提问来源于stack exchange,提问作者Mehul Chaturvedi
相关产品推荐
相关产品推荐

