Name

<-> — 返回 A 和 B 之间的 2D 距离。

Synopsis

double precision <->( geometry A , geometry B );

double precision <->( geography A , geography B );

描述

<-> 运算符返回两个几何图形之间的二维距离。 用于“ORDER BY”子句提供索引辅助的最近邻结果集。 对于 9.5 以下的 PostgreSQL 仅给出边界框的质心距离,而对于 PostgreSQL 9.5,真正的 KNN 距离搜索给出几何图形之间的真实距离以及地理的球体距离。

[Note]

该操作符将利用几何上可能可用的 2D GiST 索引。 它与其他使用空间索引的运算符不同,只有当该运算符位于 ORDER BY 子句中时才会使用空间索引。

[Note]

仅当其中一个几何图形是常量(不在子查询/cte 中)时,索引才会启动。 例如 'SRID=3005;POINT(1011102 450541)'::geometry 而不是 a.geom

有关详细示例,请参阅 PostGIS 研讨会:最近邻搜索

增强:2.2.0 -几何和地理之间的 KNN(k 最近邻)行为现在是真实的。 请注意,地理的 KNN 是在球面上计算的,而不是在椭球体平面上计算的。 PostgreSQL 9.4 及更低版本支持地理,但仅支持边界框的重心。

更改: 2.2.0 -在PostgreSQL 9.5中,旧的混合格式可能很慢。 因此,如果您只想在 PostGIS 2.2 或更高版本和 PostgreSQL 9.5 或更高版本上运行,则可能需要消除该方法。

可用性:2.0.0——弱 KNN 根据几何质心距离而不是真实距离提供最近邻。 点的结果精确,所有其他类型的结果不精确。 适用于 PostgreSQL 9.1+

示例

SELECT ST_Distance(geom, 'SRID=3005;POINT(1011102 450541)'::geometry) as d,edabbr, vaabbr
FROM va2005
ORDER BY d limit 10;

        d         | edabbr | vaabbr
------------------+--------+--------
                0 | ALQ    | 128
 5541.57712511724 | ALQ    | 129A
 5579.67450712005 | ALQ    | 001
  6083.4207708641 | ALQ    | 131
  7691.2205404848 | ALQ    | 003
 7900.75451037313 | ALQ    | 122
 8694.20710669982 | ALQ    | 129B
 9564.24289057111 | ALQ    | 130
  12089.665931705 | ALQ    | 127
 18472.5531479404 | ALQ    | 002
(10 rows)

KNN的原始答案是:

SELECT st_distance(geom, 'SRID=3005;POINT(1011102 450541)'::geometry) as d,edabbr, vaabbr
FROM va2005
ORDER BY geom <-> 'SRID=3005;POINT(1011102 450541)'::geometry limit 10;

        d         | edabbr | vaabbr
------------------+--------+--------
                0 | ALQ    | 128
 5541.57712511724 | ALQ    | 129A
 5579.67450712005 | ALQ    | 001
  6083.4207708641 | ALQ    | 131
  7691.2205404848 | ALQ    | 003
 7900.75451037313 | ALQ    | 122
 8694.20710669982 | ALQ    | 129B
 9564.24289057111 | ALQ    | 130
  12089.665931705 | ALQ    | 127
 18472.5531479404 | ALQ    | 002
(10 rows)

如果您对这两个查询运行“EXPLAIN ANALYZE”,您将看到第二个查询的性能有所提高。

对于运行 PostgreSQL < 9.5 的用户,请使用混合查询来查找真正的最临近点。 首先使用索引辅助 KNN 进行 CTE 查询,然后进行精确查询以获得正确的排序:

WITH index_query AS (
  SELECT ST_Distance(geom, 'SRID=3005;POINT(1011102 450541)'::geometry) as d,edabbr, vaabbr
        FROM va2005
  ORDER BY geom <-> 'SRID=3005;POINT(1011102 450541)'::geometry LIMIT 100)
  SELECT *
        FROM index_query
  ORDER BY d limit 10;

        d         | edabbr | vaabbr
------------------+--------+--------
                0 | ALQ    | 128
 5541.57712511724 | ALQ    | 129A
 5579.67450712005 | ALQ    | 001
  6083.4207708641 | ALQ    | 131
  7691.2205404848 | ALQ    | 003
 7900.75451037313 | ALQ    | 122
 8694.20710669982 | ALQ    | 129B
 9564.24289057111 | ALQ    | 130
  12089.665931705 | ALQ    | 127
 18472.5531479404 | ALQ    | 002
(10 rows)


相关信息

ST_DWithin, ST_Distance, <#>