<-> — 傳回 A 和 B 之間的 2D 距離。
double precision <->(
geometry A , geometry B )
;
double precision <->(
geography A , geography B )
;
<->
運算子會傳回兩個幾何物件之間的 2D 距離。在 "ORDER BY" 子句中使用時,可提供索引輔助的最近鄰結果集。對於 PostgreSQL 9.5 以下版本,只會給出邊界框的中心距離;對於 PostgreSQL 9.5+,則會進行真正的 KNN 距離搜尋,給出幾何物件之間的真實距離,以及地理位置的距離球體。
![]() |
|
此運算元將會使用幾何物件上可能存在的 2D GiST 索引。它與其他使用空間索引的運算子不同之處在於,空間索引僅在運算子位於 ORDER BY 子句中時才會使用。 |
![]() |
|
只有在其中一個幾何物件是常數(而非在子查詢/CTE 中)時,索引才會生效。例如,使用 'SRID=3005;POINT(1011102 450541)'::geometry 而非 a.geom。 |
請參閱 PostGIS workshop: Nearest-Neighbor Searching 以取得詳細範例。
增強功能:2.2.0 -- PostgreSQL 9.5+ 的幾何物件和地理位置物件支援真正的 KNN(「K 最近鄰」)行為。請注意,地理位置 KNN 是基於球體而非橢球體。對於 PostgreSQL 9.4 及更早版本,地理位置支援是新的,但僅支援中心框。
變更:2.2.0 -- 對於 PostgreSQL 9.5 的使用者,舊的混合語法可能會較慢,因此如果您的程式碼僅在 PostGIS 2.2+ 9.5+ 上執行,您會想要移除該 hack。請參閱下面的範例。
可用性: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)