mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
Cube extension kNN support
Introduce distance operators over cubes: <#> taxicab distance <-> euclidean distance <=> chebyshev distance Also add kNN support of those distances in GiST opclass. Author: Stas Kelvich
This commit is contained in:
@ -1381,6 +1381,151 @@ SELECT cube_size('(42,137)'::cube);
|
||||
0
|
||||
(1 row)
|
||||
|
||||
-- Test of distances
|
||||
--
|
||||
SELECT cube_distance('(1,1)'::cube, '(4,5)'::cube);
|
||||
cube_distance
|
||||
---------------
|
||||
5
|
||||
(1 row)
|
||||
|
||||
SELECT '(1,1)'::cube <-> '(4,5)'::cube as d_e;
|
||||
d_e
|
||||
-----
|
||||
5
|
||||
(1 row)
|
||||
|
||||
SELECT distance_chebyshev('(1,1)'::cube, '(4,5)'::cube);
|
||||
distance_chebyshev
|
||||
--------------------
|
||||
4
|
||||
(1 row)
|
||||
|
||||
SELECT '(1,1)'::cube <=> '(4,5)'::cube as d_c;
|
||||
d_c
|
||||
-----
|
||||
4
|
||||
(1 row)
|
||||
|
||||
SELECT distance_taxicab('(1,1)'::cube, '(4,5)'::cube);
|
||||
distance_taxicab
|
||||
------------------
|
||||
7
|
||||
(1 row)
|
||||
|
||||
SELECT '(1,1)'::cube <#> '(4,5)'::cube as d_t;
|
||||
d_t
|
||||
-----
|
||||
7
|
||||
(1 row)
|
||||
|
||||
-- zero for overlapping
|
||||
SELECT cube_distance('(2,2),(10,10)'::cube, '(0,0),(5,5)'::cube);
|
||||
cube_distance
|
||||
---------------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
SELECT distance_chebyshev('(2,2),(10,10)'::cube, '(0,0),(5,5)'::cube);
|
||||
distance_chebyshev
|
||||
--------------------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
SELECT distance_taxicab('(2,2),(10,10)'::cube, '(0,0),(5,5)'::cube);
|
||||
distance_taxicab
|
||||
------------------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
-- coordinate access
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->1;
|
||||
?column?
|
||||
----------
|
||||
10
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])->1;
|
||||
?column?
|
||||
----------
|
||||
40
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->6;
|
||||
?column?
|
||||
----------
|
||||
60
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->0;
|
||||
ERROR: Cube index out of bounds
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->7;
|
||||
ERROR: Cube index out of bounds
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->-1;
|
||||
ERROR: Cube index out of bounds
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->-6;
|
||||
ERROR: Cube index out of bounds
|
||||
SELECT cube(array[10,20,30])->3;
|
||||
?column?
|
||||
----------
|
||||
30
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30])->6;
|
||||
?column?
|
||||
----------
|
||||
30
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30])->-6;
|
||||
ERROR: Cube index out of bounds
|
||||
-- "normalized" coordinate access
|
||||
SELECT cube(array[10,20,30], array[40,50,60])~>1;
|
||||
?column?
|
||||
----------
|
||||
10
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>1;
|
||||
?column?
|
||||
----------
|
||||
10
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30], array[40,50,60])~>2;
|
||||
?column?
|
||||
----------
|
||||
20
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>2;
|
||||
?column?
|
||||
----------
|
||||
20
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30], array[40,50,60])~>3;
|
||||
?column?
|
||||
----------
|
||||
30
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>3;
|
||||
?column?
|
||||
----------
|
||||
30
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>0;
|
||||
ERROR: Cube index out of bounds
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>4;
|
||||
?column?
|
||||
----------
|
||||
40
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>(-1);
|
||||
ERROR: Cube index out of bounds
|
||||
-- Load some example data and build the index
|
||||
--
|
||||
CREATE TABLE test_cube (c cube);
|
||||
@ -1407,3 +1552,159 @@ SELECT * FROM test_cube WHERE c && '(3000,1000),(0,0)' GROUP BY c ORDER BY c;
|
||||
(2424, 160),(2424, 81)
|
||||
(5 rows)
|
||||
|
||||
-- kNN with index
|
||||
SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5;
|
||||
c | dist
|
||||
-------------------------+------------------
|
||||
(337, 455),(240, 359) | 0
|
||||
(759, 187),(662, 163) | 162
|
||||
(948, 1201),(907, 1156) | 772.000647668122
|
||||
(1444, 403),(1346, 344) | 846
|
||||
(369, 1457),(278, 1409) | 909
|
||||
(5 rows)
|
||||
|
||||
SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5;
|
||||
c | dist
|
||||
-------------------------+------
|
||||
(337, 455),(240, 359) | 0
|
||||
(759, 187),(662, 163) | 162
|
||||
(948, 1201),(907, 1156) | 656
|
||||
(1444, 403),(1346, 344) | 846
|
||||
(369, 1457),(278, 1409) | 909
|
||||
(5 rows)
|
||||
|
||||
SELECT *, c <#> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <#> '(100, 100),(500, 500)'::cube LIMIT 5;
|
||||
c | dist
|
||||
-------------------------+------
|
||||
(337, 455),(240, 359) | 0
|
||||
(759, 187),(662, 163) | 162
|
||||
(1444, 403),(1346, 344) | 846
|
||||
(369, 1457),(278, 1409) | 909
|
||||
(948, 1201),(907, 1156) | 1063
|
||||
(5 rows)
|
||||
|
||||
-- kNN-based sorting
|
||||
SELECT * FROM test_cube ORDER BY c~>1 LIMIT 15; -- ascending by 1st coordinate of lower left corner
|
||||
c
|
||||
---------------------------
|
||||
(54, 38679),(3, 38602)
|
||||
(83, 10271),(15, 10265)
|
||||
(122, 46832),(64, 46762)
|
||||
(167, 17214),(92, 17184)
|
||||
(161, 24465),(107, 24374)
|
||||
(162, 26040),(120, 25963)
|
||||
(154, 4019),(138, 3990)
|
||||
(259, 1850),(175, 1820)
|
||||
(207, 40886),(179, 40879)
|
||||
(288, 49588),(204, 49571)
|
||||
(270, 32616),(226, 32607)
|
||||
(318, 31489),(235, 31404)
|
||||
(337, 455),(240, 359)
|
||||
(270, 29508),(264, 29440)
|
||||
(369, 1457),(278, 1409)
|
||||
(15 rows)
|
||||
|
||||
SELECT * FROM test_cube ORDER BY c~>4 LIMIT 15; -- ascending by 2nd coordinate or upper right corner
|
||||
c
|
||||
---------------------------
|
||||
(30333, 50),(30273, 6)
|
||||
(43301, 75),(43227, 43)
|
||||
(19650, 142),(19630, 51)
|
||||
(2424, 160),(2424, 81)
|
||||
(3449, 171),(3354, 108)
|
||||
(18037, 155),(17941, 109)
|
||||
(28511, 208),(28479, 114)
|
||||
(19946, 217),(19941, 118)
|
||||
(16906, 191),(16816, 139)
|
||||
(759, 187),(662, 163)
|
||||
(22684, 266),(22656, 181)
|
||||
(24423, 255),(24360, 213)
|
||||
(45989, 249),(45910, 222)
|
||||
(11399, 377),(11360, 294)
|
||||
(12162, 389),(12103, 309)
|
||||
(15 rows)
|
||||
|
||||
SELECT * FROM test_cube ORDER BY c~>1 DESC LIMIT 15; -- descending by 1st coordinate of lower left corner
|
||||
c
|
||||
-------------------------------
|
||||
(50027, 49230),(49951, 49214)
|
||||
(49980, 35004),(49937, 34963)
|
||||
(49985, 6436),(49927, 6338)
|
||||
(49999, 27218),(49908, 27176)
|
||||
(49954, 1340),(49905, 1294)
|
||||
(49944, 25163),(49902, 25153)
|
||||
(49981, 34876),(49898, 34786)
|
||||
(49957, 43390),(49897, 43384)
|
||||
(49853, 18504),(49848, 18503)
|
||||
(49902, 41752),(49818, 41746)
|
||||
(49907, 30225),(49810, 30158)
|
||||
(49843, 5175),(49808, 5145)
|
||||
(49887, 24274),(49805, 24184)
|
||||
(49847, 7128),(49798, 7067)
|
||||
(49820, 7990),(49771, 7967)
|
||||
(15 rows)
|
||||
|
||||
SELECT * FROM test_cube ORDER BY c~>4 DESC LIMIT 15; -- descending by 2nd coordinate or upper right corner
|
||||
c
|
||||
-------------------------------
|
||||
(36311, 50073),(36258, 49987)
|
||||
(30746, 50040),(30727, 49992)
|
||||
(2168, 50012),(2108, 49914)
|
||||
(21551, 49983),(21492, 49885)
|
||||
(17954, 49975),(17865, 49915)
|
||||
(3531, 49962),(3463, 49934)
|
||||
(19128, 49932),(19112, 49849)
|
||||
(31287, 49923),(31236, 49913)
|
||||
(43925, 49912),(43888, 49878)
|
||||
(29261, 49910),(29247, 49818)
|
||||
(14913, 49873),(14849, 49836)
|
||||
(20007, 49858),(19921, 49778)
|
||||
(38266, 49852),(38233, 49844)
|
||||
(37595, 49849),(37581, 49834)
|
||||
(46151, 49848),(46058, 49830)
|
||||
(15 rows)
|
||||
|
||||
-- same thing for index with points
|
||||
CREATE TABLE test_point(c cube);
|
||||
INSERT INTO test_point(SELECT cube(array[c->1,c->2,c->3,c->4]) FROM test_cube);
|
||||
CREATE INDEX ON test_point USING gist(c);
|
||||
SELECT * FROM test_point ORDER BY c~>1, c~>2 LIMIT 15; -- ascending by 1st then by 2nd coordinate
|
||||
c
|
||||
--------------------------
|
||||
(54, 38679, 3, 38602)
|
||||
(83, 10271, 15, 10265)
|
||||
(122, 46832, 64, 46762)
|
||||
(154, 4019, 138, 3990)
|
||||
(161, 24465, 107, 24374)
|
||||
(162, 26040, 120, 25963)
|
||||
(167, 17214, 92, 17184)
|
||||
(207, 40886, 179, 40879)
|
||||
(259, 1850, 175, 1820)
|
||||
(270, 29508, 264, 29440)
|
||||
(270, 32616, 226, 32607)
|
||||
(288, 49588, 204, 49571)
|
||||
(318, 31489, 235, 31404)
|
||||
(326, 18837, 285, 18817)
|
||||
(337, 455, 240, 359)
|
||||
(15 rows)
|
||||
|
||||
SELECT * FROM test_point ORDER BY c~>4 DESC LIMIT 15; -- descending by 1st coordinate
|
||||
c
|
||||
------------------------------
|
||||
(30746, 50040, 30727, 49992)
|
||||
(36311, 50073, 36258, 49987)
|
||||
(3531, 49962, 3463, 49934)
|
||||
(17954, 49975, 17865, 49915)
|
||||
(2168, 50012, 2108, 49914)
|
||||
(31287, 49923, 31236, 49913)
|
||||
(21551, 49983, 21492, 49885)
|
||||
(43925, 49912, 43888, 49878)
|
||||
(19128, 49932, 19112, 49849)
|
||||
(38266, 49852, 38233, 49844)
|
||||
(14913, 49873, 14849, 49836)
|
||||
(37595, 49849, 37581, 49834)
|
||||
(46151, 49848, 46058, 49830)
|
||||
(29261, 49910, 29247, 49818)
|
||||
(19233, 49824, 19185, 49794)
|
||||
(15 rows)
|
||||
|
||||
|
@ -1381,6 +1381,151 @@ SELECT cube_size('(42,137)'::cube);
|
||||
0
|
||||
(1 row)
|
||||
|
||||
-- Test of distances
|
||||
--
|
||||
SELECT cube_distance('(1,1)'::cube, '(4,5)'::cube);
|
||||
cube_distance
|
||||
---------------
|
||||
5
|
||||
(1 row)
|
||||
|
||||
SELECT '(1,1)'::cube <-> '(4,5)'::cube as d_e;
|
||||
d_e
|
||||
-----
|
||||
5
|
||||
(1 row)
|
||||
|
||||
SELECT distance_chebyshev('(1,1)'::cube, '(4,5)'::cube);
|
||||
distance_chebyshev
|
||||
--------------------
|
||||
4
|
||||
(1 row)
|
||||
|
||||
SELECT '(1,1)'::cube <=> '(4,5)'::cube as d_c;
|
||||
d_c
|
||||
-----
|
||||
4
|
||||
(1 row)
|
||||
|
||||
SELECT distance_taxicab('(1,1)'::cube, '(4,5)'::cube);
|
||||
distance_taxicab
|
||||
------------------
|
||||
7
|
||||
(1 row)
|
||||
|
||||
SELECT '(1,1)'::cube <#> '(4,5)'::cube as d_t;
|
||||
d_t
|
||||
-----
|
||||
7
|
||||
(1 row)
|
||||
|
||||
-- zero for overlapping
|
||||
SELECT cube_distance('(2,2),(10,10)'::cube, '(0,0),(5,5)'::cube);
|
||||
cube_distance
|
||||
---------------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
SELECT distance_chebyshev('(2,2),(10,10)'::cube, '(0,0),(5,5)'::cube);
|
||||
distance_chebyshev
|
||||
--------------------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
SELECT distance_taxicab('(2,2),(10,10)'::cube, '(0,0),(5,5)'::cube);
|
||||
distance_taxicab
|
||||
------------------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
-- coordinate access
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->1;
|
||||
?column?
|
||||
----------
|
||||
10
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])->1;
|
||||
?column?
|
||||
----------
|
||||
40
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->6;
|
||||
?column?
|
||||
----------
|
||||
60
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->0;
|
||||
ERROR: Cube index out of bounds
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->7;
|
||||
ERROR: Cube index out of bounds
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->-1;
|
||||
ERROR: Cube index out of bounds
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->-6;
|
||||
ERROR: Cube index out of bounds
|
||||
SELECT cube(array[10,20,30])->3;
|
||||
?column?
|
||||
----------
|
||||
30
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30])->6;
|
||||
?column?
|
||||
----------
|
||||
30
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30])->-6;
|
||||
ERROR: Cube index out of bounds
|
||||
-- "normalized" coordinate access
|
||||
SELECT cube(array[10,20,30], array[40,50,60])~>1;
|
||||
?column?
|
||||
----------
|
||||
10
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>1;
|
||||
?column?
|
||||
----------
|
||||
10
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30], array[40,50,60])~>2;
|
||||
?column?
|
||||
----------
|
||||
20
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>2;
|
||||
?column?
|
||||
----------
|
||||
20
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30], array[40,50,60])~>3;
|
||||
?column?
|
||||
----------
|
||||
30
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>3;
|
||||
?column?
|
||||
----------
|
||||
30
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>0;
|
||||
ERROR: Cube index out of bounds
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>4;
|
||||
?column?
|
||||
----------
|
||||
40
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>(-1);
|
||||
ERROR: Cube index out of bounds
|
||||
-- Load some example data and build the index
|
||||
--
|
||||
CREATE TABLE test_cube (c cube);
|
||||
@ -1407,3 +1552,159 @@ SELECT * FROM test_cube WHERE c && '(3000,1000),(0,0)' GROUP BY c ORDER BY c;
|
||||
(2424, 160),(2424, 81)
|
||||
(5 rows)
|
||||
|
||||
-- kNN with index
|
||||
SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5;
|
||||
c | dist
|
||||
-------------------------+------------------
|
||||
(337, 455),(240, 359) | 0
|
||||
(759, 187),(662, 163) | 162
|
||||
(948, 1201),(907, 1156) | 772.000647668122
|
||||
(1444, 403),(1346, 344) | 846
|
||||
(369, 1457),(278, 1409) | 909
|
||||
(5 rows)
|
||||
|
||||
SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5;
|
||||
c | dist
|
||||
-------------------------+------
|
||||
(337, 455),(240, 359) | 0
|
||||
(759, 187),(662, 163) | 162
|
||||
(948, 1201),(907, 1156) | 656
|
||||
(1444, 403),(1346, 344) | 846
|
||||
(369, 1457),(278, 1409) | 909
|
||||
(5 rows)
|
||||
|
||||
SELECT *, c <#> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <#> '(100, 100),(500, 500)'::cube LIMIT 5;
|
||||
c | dist
|
||||
-------------------------+------
|
||||
(337, 455),(240, 359) | 0
|
||||
(759, 187),(662, 163) | 162
|
||||
(1444, 403),(1346, 344) | 846
|
||||
(369, 1457),(278, 1409) | 909
|
||||
(948, 1201),(907, 1156) | 1063
|
||||
(5 rows)
|
||||
|
||||
-- kNN-based sorting
|
||||
SELECT * FROM test_cube ORDER BY c~>1 LIMIT 15; -- ascending by 1st coordinate of lower left corner
|
||||
c
|
||||
---------------------------
|
||||
(54, 38679),(3, 38602)
|
||||
(83, 10271),(15, 10265)
|
||||
(122, 46832),(64, 46762)
|
||||
(167, 17214),(92, 17184)
|
||||
(161, 24465),(107, 24374)
|
||||
(162, 26040),(120, 25963)
|
||||
(154, 4019),(138, 3990)
|
||||
(259, 1850),(175, 1820)
|
||||
(207, 40886),(179, 40879)
|
||||
(288, 49588),(204, 49571)
|
||||
(270, 32616),(226, 32607)
|
||||
(318, 31489),(235, 31404)
|
||||
(337, 455),(240, 359)
|
||||
(270, 29508),(264, 29440)
|
||||
(369, 1457),(278, 1409)
|
||||
(15 rows)
|
||||
|
||||
SELECT * FROM test_cube ORDER BY c~>4 LIMIT 15; -- ascending by 2nd coordinate or upper right corner
|
||||
c
|
||||
---------------------------
|
||||
(30333, 50),(30273, 6)
|
||||
(43301, 75),(43227, 43)
|
||||
(19650, 142),(19630, 51)
|
||||
(2424, 160),(2424, 81)
|
||||
(3449, 171),(3354, 108)
|
||||
(18037, 155),(17941, 109)
|
||||
(28511, 208),(28479, 114)
|
||||
(19946, 217),(19941, 118)
|
||||
(16906, 191),(16816, 139)
|
||||
(759, 187),(662, 163)
|
||||
(22684, 266),(22656, 181)
|
||||
(24423, 255),(24360, 213)
|
||||
(45989, 249),(45910, 222)
|
||||
(11399, 377),(11360, 294)
|
||||
(12162, 389),(12103, 309)
|
||||
(15 rows)
|
||||
|
||||
SELECT * FROM test_cube ORDER BY c~>1 DESC LIMIT 15; -- descending by 1st coordinate of lower left corner
|
||||
c
|
||||
-------------------------------
|
||||
(50027, 49230),(49951, 49214)
|
||||
(49980, 35004),(49937, 34963)
|
||||
(49985, 6436),(49927, 6338)
|
||||
(49999, 27218),(49908, 27176)
|
||||
(49954, 1340),(49905, 1294)
|
||||
(49944, 25163),(49902, 25153)
|
||||
(49981, 34876),(49898, 34786)
|
||||
(49957, 43390),(49897, 43384)
|
||||
(49853, 18504),(49848, 18503)
|
||||
(49902, 41752),(49818, 41746)
|
||||
(49907, 30225),(49810, 30158)
|
||||
(49843, 5175),(49808, 5145)
|
||||
(49887, 24274),(49805, 24184)
|
||||
(49847, 7128),(49798, 7067)
|
||||
(49820, 7990),(49771, 7967)
|
||||
(15 rows)
|
||||
|
||||
SELECT * FROM test_cube ORDER BY c~>4 DESC LIMIT 15; -- descending by 2nd coordinate or upper right corner
|
||||
c
|
||||
-------------------------------
|
||||
(36311, 50073),(36258, 49987)
|
||||
(30746, 50040),(30727, 49992)
|
||||
(2168, 50012),(2108, 49914)
|
||||
(21551, 49983),(21492, 49885)
|
||||
(17954, 49975),(17865, 49915)
|
||||
(3531, 49962),(3463, 49934)
|
||||
(19128, 49932),(19112, 49849)
|
||||
(31287, 49923),(31236, 49913)
|
||||
(43925, 49912),(43888, 49878)
|
||||
(29261, 49910),(29247, 49818)
|
||||
(14913, 49873),(14849, 49836)
|
||||
(20007, 49858),(19921, 49778)
|
||||
(38266, 49852),(38233, 49844)
|
||||
(37595, 49849),(37581, 49834)
|
||||
(46151, 49848),(46058, 49830)
|
||||
(15 rows)
|
||||
|
||||
-- same thing for index with points
|
||||
CREATE TABLE test_point(c cube);
|
||||
INSERT INTO test_point(SELECT cube(array[c->1,c->2,c->3,c->4]) FROM test_cube);
|
||||
CREATE INDEX ON test_point USING gist(c);
|
||||
SELECT * FROM test_point ORDER BY c~>1, c~>2 LIMIT 15; -- ascending by 1st then by 2nd coordinate
|
||||
c
|
||||
--------------------------
|
||||
(54, 38679, 3, 38602)
|
||||
(83, 10271, 15, 10265)
|
||||
(122, 46832, 64, 46762)
|
||||
(154, 4019, 138, 3990)
|
||||
(161, 24465, 107, 24374)
|
||||
(162, 26040, 120, 25963)
|
||||
(167, 17214, 92, 17184)
|
||||
(207, 40886, 179, 40879)
|
||||
(259, 1850, 175, 1820)
|
||||
(270, 29508, 264, 29440)
|
||||
(270, 32616, 226, 32607)
|
||||
(288, 49588, 204, 49571)
|
||||
(318, 31489, 235, 31404)
|
||||
(326, 18837, 285, 18817)
|
||||
(337, 455, 240, 359)
|
||||
(15 rows)
|
||||
|
||||
SELECT * FROM test_point ORDER BY c~>4 DESC LIMIT 15; -- descending by 1st coordinate
|
||||
c
|
||||
------------------------------
|
||||
(30746, 50040, 30727, 49992)
|
||||
(36311, 50073, 36258, 49987)
|
||||
(3531, 49962, 3463, 49934)
|
||||
(17954, 49975, 17865, 49915)
|
||||
(2168, 50012, 2108, 49914)
|
||||
(31287, 49923, 31236, 49913)
|
||||
(21551, 49983, 21492, 49885)
|
||||
(43925, 49912, 43888, 49878)
|
||||
(19128, 49932, 19112, 49849)
|
||||
(38266, 49852, 38233, 49844)
|
||||
(14913, 49873, 14849, 49836)
|
||||
(37595, 49849, 37581, 49834)
|
||||
(46151, 49848, 46058, 49830)
|
||||
(29261, 49910, 29247, 49818)
|
||||
(19233, 49824, 19185, 49794)
|
||||
(15 rows)
|
||||
|
||||
|
@ -1381,6 +1381,151 @@ SELECT cube_size('(42,137)'::cube);
|
||||
0
|
||||
(1 row)
|
||||
|
||||
-- Test of distances
|
||||
--
|
||||
SELECT cube_distance('(1,1)'::cube, '(4,5)'::cube);
|
||||
cube_distance
|
||||
---------------
|
||||
5
|
||||
(1 row)
|
||||
|
||||
SELECT '(1,1)'::cube <-> '(4,5)'::cube as d_e;
|
||||
d_e
|
||||
-----
|
||||
5
|
||||
(1 row)
|
||||
|
||||
SELECT distance_chebyshev('(1,1)'::cube, '(4,5)'::cube);
|
||||
distance_chebyshev
|
||||
--------------------
|
||||
4
|
||||
(1 row)
|
||||
|
||||
SELECT '(1,1)'::cube <=> '(4,5)'::cube as d_c;
|
||||
d_c
|
||||
-----
|
||||
4
|
||||
(1 row)
|
||||
|
||||
SELECT distance_taxicab('(1,1)'::cube, '(4,5)'::cube);
|
||||
distance_taxicab
|
||||
------------------
|
||||
7
|
||||
(1 row)
|
||||
|
||||
SELECT '(1,1)'::cube <#> '(4,5)'::cube as d_t;
|
||||
d_t
|
||||
-----
|
||||
7
|
||||
(1 row)
|
||||
|
||||
-- zero for overlapping
|
||||
SELECT cube_distance('(2,2),(10,10)'::cube, '(0,0),(5,5)'::cube);
|
||||
cube_distance
|
||||
---------------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
SELECT distance_chebyshev('(2,2),(10,10)'::cube, '(0,0),(5,5)'::cube);
|
||||
distance_chebyshev
|
||||
--------------------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
SELECT distance_taxicab('(2,2),(10,10)'::cube, '(0,0),(5,5)'::cube);
|
||||
distance_taxicab
|
||||
------------------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
-- coordinate access
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->1;
|
||||
?column?
|
||||
----------
|
||||
10
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])->1;
|
||||
?column?
|
||||
----------
|
||||
40
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->6;
|
||||
?column?
|
||||
----------
|
||||
60
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->0;
|
||||
ERROR: Cube index out of bounds
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->7;
|
||||
ERROR: Cube index out of bounds
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->-1;
|
||||
ERROR: Cube index out of bounds
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->-6;
|
||||
ERROR: Cube index out of bounds
|
||||
SELECT cube(array[10,20,30])->3;
|
||||
?column?
|
||||
----------
|
||||
30
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30])->6;
|
||||
?column?
|
||||
----------
|
||||
30
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30])->-6;
|
||||
ERROR: Cube index out of bounds
|
||||
-- "normalized" coordinate access
|
||||
SELECT cube(array[10,20,30], array[40,50,60])~>1;
|
||||
?column?
|
||||
----------
|
||||
10
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>1;
|
||||
?column?
|
||||
----------
|
||||
10
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30], array[40,50,60])~>2;
|
||||
?column?
|
||||
----------
|
||||
20
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>2;
|
||||
?column?
|
||||
----------
|
||||
20
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30], array[40,50,60])~>3;
|
||||
?column?
|
||||
----------
|
||||
30
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>3;
|
||||
?column?
|
||||
----------
|
||||
30
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>0;
|
||||
ERROR: Cube index out of bounds
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>4;
|
||||
?column?
|
||||
----------
|
||||
40
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>(-1);
|
||||
ERROR: Cube index out of bounds
|
||||
-- Load some example data and build the index
|
||||
--
|
||||
CREATE TABLE test_cube (c cube);
|
||||
@ -1407,3 +1552,159 @@ SELECT * FROM test_cube WHERE c && '(3000,1000),(0,0)' GROUP BY c ORDER BY c;
|
||||
(2424, 160),(2424, 81)
|
||||
(5 rows)
|
||||
|
||||
-- kNN with index
|
||||
SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5;
|
||||
c | dist
|
||||
-------------------------+------------------
|
||||
(337, 455),(240, 359) | 0
|
||||
(759, 187),(662, 163) | 162
|
||||
(948, 1201),(907, 1156) | 772.000647668122
|
||||
(1444, 403),(1346, 344) | 846
|
||||
(369, 1457),(278, 1409) | 909
|
||||
(5 rows)
|
||||
|
||||
SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5;
|
||||
c | dist
|
||||
-------------------------+------
|
||||
(337, 455),(240, 359) | 0
|
||||
(759, 187),(662, 163) | 162
|
||||
(948, 1201),(907, 1156) | 656
|
||||
(1444, 403),(1346, 344) | 846
|
||||
(369, 1457),(278, 1409) | 909
|
||||
(5 rows)
|
||||
|
||||
SELECT *, c <#> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <#> '(100, 100),(500, 500)'::cube LIMIT 5;
|
||||
c | dist
|
||||
-------------------------+------
|
||||
(337, 455),(240, 359) | 0
|
||||
(759, 187),(662, 163) | 162
|
||||
(1444, 403),(1346, 344) | 846
|
||||
(369, 1457),(278, 1409) | 909
|
||||
(948, 1201),(907, 1156) | 1063
|
||||
(5 rows)
|
||||
|
||||
-- kNN-based sorting
|
||||
SELECT * FROM test_cube ORDER BY c~>1 LIMIT 15; -- ascending by 1st coordinate of lower left corner
|
||||
c
|
||||
---------------------------
|
||||
(54, 38679),(3, 38602)
|
||||
(83, 10271),(15, 10265)
|
||||
(122, 46832),(64, 46762)
|
||||
(167, 17214),(92, 17184)
|
||||
(161, 24465),(107, 24374)
|
||||
(162, 26040),(120, 25963)
|
||||
(154, 4019),(138, 3990)
|
||||
(259, 1850),(175, 1820)
|
||||
(207, 40886),(179, 40879)
|
||||
(288, 49588),(204, 49571)
|
||||
(270, 32616),(226, 32607)
|
||||
(318, 31489),(235, 31404)
|
||||
(337, 455),(240, 359)
|
||||
(270, 29508),(264, 29440)
|
||||
(369, 1457),(278, 1409)
|
||||
(15 rows)
|
||||
|
||||
SELECT * FROM test_cube ORDER BY c~>4 LIMIT 15; -- ascending by 2nd coordinate or upper right corner
|
||||
c
|
||||
---------------------------
|
||||
(30333, 50),(30273, 6)
|
||||
(43301, 75),(43227, 43)
|
||||
(19650, 142),(19630, 51)
|
||||
(2424, 160),(2424, 81)
|
||||
(3449, 171),(3354, 108)
|
||||
(18037, 155),(17941, 109)
|
||||
(28511, 208),(28479, 114)
|
||||
(19946, 217),(19941, 118)
|
||||
(16906, 191),(16816, 139)
|
||||
(759, 187),(662, 163)
|
||||
(22684, 266),(22656, 181)
|
||||
(24423, 255),(24360, 213)
|
||||
(45989, 249),(45910, 222)
|
||||
(11399, 377),(11360, 294)
|
||||
(12162, 389),(12103, 309)
|
||||
(15 rows)
|
||||
|
||||
SELECT * FROM test_cube ORDER BY c~>1 DESC LIMIT 15; -- descending by 1st coordinate of lower left corner
|
||||
c
|
||||
-------------------------------
|
||||
(50027, 49230),(49951, 49214)
|
||||
(49980, 35004),(49937, 34963)
|
||||
(49985, 6436),(49927, 6338)
|
||||
(49999, 27218),(49908, 27176)
|
||||
(49954, 1340),(49905, 1294)
|
||||
(49944, 25163),(49902, 25153)
|
||||
(49981, 34876),(49898, 34786)
|
||||
(49957, 43390),(49897, 43384)
|
||||
(49853, 18504),(49848, 18503)
|
||||
(49902, 41752),(49818, 41746)
|
||||
(49907, 30225),(49810, 30158)
|
||||
(49843, 5175),(49808, 5145)
|
||||
(49887, 24274),(49805, 24184)
|
||||
(49847, 7128),(49798, 7067)
|
||||
(49820, 7990),(49771, 7967)
|
||||
(15 rows)
|
||||
|
||||
SELECT * FROM test_cube ORDER BY c~>4 DESC LIMIT 15; -- descending by 2nd coordinate or upper right corner
|
||||
c
|
||||
-------------------------------
|
||||
(36311, 50073),(36258, 49987)
|
||||
(30746, 50040),(30727, 49992)
|
||||
(2168, 50012),(2108, 49914)
|
||||
(21551, 49983),(21492, 49885)
|
||||
(17954, 49975),(17865, 49915)
|
||||
(3531, 49962),(3463, 49934)
|
||||
(19128, 49932),(19112, 49849)
|
||||
(31287, 49923),(31236, 49913)
|
||||
(43925, 49912),(43888, 49878)
|
||||
(29261, 49910),(29247, 49818)
|
||||
(14913, 49873),(14849, 49836)
|
||||
(20007, 49858),(19921, 49778)
|
||||
(38266, 49852),(38233, 49844)
|
||||
(37595, 49849),(37581, 49834)
|
||||
(46151, 49848),(46058, 49830)
|
||||
(15 rows)
|
||||
|
||||
-- same thing for index with points
|
||||
CREATE TABLE test_point(c cube);
|
||||
INSERT INTO test_point(SELECT cube(array[c->1,c->2,c->3,c->4]) FROM test_cube);
|
||||
CREATE INDEX ON test_point USING gist(c);
|
||||
SELECT * FROM test_point ORDER BY c~>1, c~>2 LIMIT 15; -- ascending by 1st then by 2nd coordinate
|
||||
c
|
||||
--------------------------
|
||||
(54, 38679, 3, 38602)
|
||||
(83, 10271, 15, 10265)
|
||||
(122, 46832, 64, 46762)
|
||||
(154, 4019, 138, 3990)
|
||||
(161, 24465, 107, 24374)
|
||||
(162, 26040, 120, 25963)
|
||||
(167, 17214, 92, 17184)
|
||||
(207, 40886, 179, 40879)
|
||||
(259, 1850, 175, 1820)
|
||||
(270, 29508, 264, 29440)
|
||||
(270, 32616, 226, 32607)
|
||||
(288, 49588, 204, 49571)
|
||||
(318, 31489, 235, 31404)
|
||||
(326, 18837, 285, 18817)
|
||||
(337, 455, 240, 359)
|
||||
(15 rows)
|
||||
|
||||
SELECT * FROM test_point ORDER BY c~>4 DESC LIMIT 15; -- descending by 1st coordinate
|
||||
c
|
||||
------------------------------
|
||||
(30746, 50040, 30727, 49992)
|
||||
(36311, 50073, 36258, 49987)
|
||||
(3531, 49962, 3463, 49934)
|
||||
(17954, 49975, 17865, 49915)
|
||||
(2168, 50012, 2108, 49914)
|
||||
(31287, 49923, 31236, 49913)
|
||||
(21551, 49983, 21492, 49885)
|
||||
(43925, 49912, 43888, 49878)
|
||||
(19128, 49932, 19112, 49849)
|
||||
(38266, 49852, 38233, 49844)
|
||||
(14913, 49873, 14849, 49836)
|
||||
(37595, 49849, 37581, 49834)
|
||||
(46151, 49848, 46058, 49830)
|
||||
(29261, 49910, 29247, 49818)
|
||||
(19233, 49824, 19185, 49794)
|
||||
(15 rows)
|
||||
|
||||
|
@ -1381,6 +1381,151 @@ SELECT cube_size('(42,137)'::cube);
|
||||
0
|
||||
(1 row)
|
||||
|
||||
-- Test of distances
|
||||
--
|
||||
SELECT cube_distance('(1,1)'::cube, '(4,5)'::cube);
|
||||
cube_distance
|
||||
---------------
|
||||
5
|
||||
(1 row)
|
||||
|
||||
SELECT '(1,1)'::cube <-> '(4,5)'::cube as d_e;
|
||||
d_e
|
||||
-----
|
||||
5
|
||||
(1 row)
|
||||
|
||||
SELECT distance_chebyshev('(1,1)'::cube, '(4,5)'::cube);
|
||||
distance_chebyshev
|
||||
--------------------
|
||||
4
|
||||
(1 row)
|
||||
|
||||
SELECT '(1,1)'::cube <=> '(4,5)'::cube as d_c;
|
||||
d_c
|
||||
-----
|
||||
4
|
||||
(1 row)
|
||||
|
||||
SELECT distance_taxicab('(1,1)'::cube, '(4,5)'::cube);
|
||||
distance_taxicab
|
||||
------------------
|
||||
7
|
||||
(1 row)
|
||||
|
||||
SELECT '(1,1)'::cube <#> '(4,5)'::cube as d_t;
|
||||
d_t
|
||||
-----
|
||||
7
|
||||
(1 row)
|
||||
|
||||
-- zero for overlapping
|
||||
SELECT cube_distance('(2,2),(10,10)'::cube, '(0,0),(5,5)'::cube);
|
||||
cube_distance
|
||||
---------------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
SELECT distance_chebyshev('(2,2),(10,10)'::cube, '(0,0),(5,5)'::cube);
|
||||
distance_chebyshev
|
||||
--------------------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
SELECT distance_taxicab('(2,2),(10,10)'::cube, '(0,0),(5,5)'::cube);
|
||||
distance_taxicab
|
||||
------------------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
-- coordinate access
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->1;
|
||||
?column?
|
||||
----------
|
||||
10
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])->1;
|
||||
?column?
|
||||
----------
|
||||
40
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->6;
|
||||
?column?
|
||||
----------
|
||||
60
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->0;
|
||||
ERROR: Cube index out of bounds
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->7;
|
||||
ERROR: Cube index out of bounds
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->-1;
|
||||
ERROR: Cube index out of bounds
|
||||
SELECT cube(array[10,20,30], array[40,50,60])->-6;
|
||||
ERROR: Cube index out of bounds
|
||||
SELECT cube(array[10,20,30])->3;
|
||||
?column?
|
||||
----------
|
||||
30
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30])->6;
|
||||
?column?
|
||||
----------
|
||||
30
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30])->-6;
|
||||
ERROR: Cube index out of bounds
|
||||
-- "normalized" coordinate access
|
||||
SELECT cube(array[10,20,30], array[40,50,60])~>1;
|
||||
?column?
|
||||
----------
|
||||
10
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>1;
|
||||
?column?
|
||||
----------
|
||||
10
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30], array[40,50,60])~>2;
|
||||
?column?
|
||||
----------
|
||||
20
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>2;
|
||||
?column?
|
||||
----------
|
||||
20
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[10,20,30], array[40,50,60])~>3;
|
||||
?column?
|
||||
----------
|
||||
30
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>3;
|
||||
?column?
|
||||
----------
|
||||
30
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>0;
|
||||
ERROR: Cube index out of bounds
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>4;
|
||||
?column?
|
||||
----------
|
||||
40
|
||||
(1 row)
|
||||
|
||||
SELECT cube(array[40,50,60], array[10,20,30])~>(-1);
|
||||
ERROR: Cube index out of bounds
|
||||
-- Load some example data and build the index
|
||||
--
|
||||
CREATE TABLE test_cube (c cube);
|
||||
@ -1407,3 +1552,159 @@ SELECT * FROM test_cube WHERE c && '(3000,1000),(0,0)' GROUP BY c ORDER BY c;
|
||||
(2424, 160),(2424, 81)
|
||||
(5 rows)
|
||||
|
||||
-- kNN with index
|
||||
SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5;
|
||||
c | dist
|
||||
-------------------------+------------------
|
||||
(337, 455),(240, 359) | 0
|
||||
(759, 187),(662, 163) | 162
|
||||
(948, 1201),(907, 1156) | 772.000647668122
|
||||
(1444, 403),(1346, 344) | 846
|
||||
(369, 1457),(278, 1409) | 909
|
||||
(5 rows)
|
||||
|
||||
SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5;
|
||||
c | dist
|
||||
-------------------------+------
|
||||
(337, 455),(240, 359) | 0
|
||||
(759, 187),(662, 163) | 162
|
||||
(948, 1201),(907, 1156) | 656
|
||||
(1444, 403),(1346, 344) | 846
|
||||
(369, 1457),(278, 1409) | 909
|
||||
(5 rows)
|
||||
|
||||
SELECT *, c <#> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <#> '(100, 100),(500, 500)'::cube LIMIT 5;
|
||||
c | dist
|
||||
-------------------------+------
|
||||
(337, 455),(240, 359) | 0
|
||||
(759, 187),(662, 163) | 162
|
||||
(1444, 403),(1346, 344) | 846
|
||||
(369, 1457),(278, 1409) | 909
|
||||
(948, 1201),(907, 1156) | 1063
|
||||
(5 rows)
|
||||
|
||||
-- kNN-based sorting
|
||||
SELECT * FROM test_cube ORDER BY c~>1 LIMIT 15; -- ascending by 1st coordinate of lower left corner
|
||||
c
|
||||
---------------------------
|
||||
(54, 38679),(3, 38602)
|
||||
(83, 10271),(15, 10265)
|
||||
(122, 46832),(64, 46762)
|
||||
(167, 17214),(92, 17184)
|
||||
(161, 24465),(107, 24374)
|
||||
(162, 26040),(120, 25963)
|
||||
(154, 4019),(138, 3990)
|
||||
(259, 1850),(175, 1820)
|
||||
(207, 40886),(179, 40879)
|
||||
(288, 49588),(204, 49571)
|
||||
(270, 32616),(226, 32607)
|
||||
(318, 31489),(235, 31404)
|
||||
(337, 455),(240, 359)
|
||||
(270, 29508),(264, 29440)
|
||||
(369, 1457),(278, 1409)
|
||||
(15 rows)
|
||||
|
||||
SELECT * FROM test_cube ORDER BY c~>4 LIMIT 15; -- ascending by 2nd coordinate or upper right corner
|
||||
c
|
||||
---------------------------
|
||||
(30333, 50),(30273, 6)
|
||||
(43301, 75),(43227, 43)
|
||||
(19650, 142),(19630, 51)
|
||||
(2424, 160),(2424, 81)
|
||||
(3449, 171),(3354, 108)
|
||||
(18037, 155),(17941, 109)
|
||||
(28511, 208),(28479, 114)
|
||||
(19946, 217),(19941, 118)
|
||||
(16906, 191),(16816, 139)
|
||||
(759, 187),(662, 163)
|
||||
(22684, 266),(22656, 181)
|
||||
(24423, 255),(24360, 213)
|
||||
(45989, 249),(45910, 222)
|
||||
(11399, 377),(11360, 294)
|
||||
(12162, 389),(12103, 309)
|
||||
(15 rows)
|
||||
|
||||
SELECT * FROM test_cube ORDER BY c~>1 DESC LIMIT 15; -- descending by 1st coordinate of lower left corner
|
||||
c
|
||||
-------------------------------
|
||||
(50027, 49230),(49951, 49214)
|
||||
(49980, 35004),(49937, 34963)
|
||||
(49985, 6436),(49927, 6338)
|
||||
(49999, 27218),(49908, 27176)
|
||||
(49954, 1340),(49905, 1294)
|
||||
(49944, 25163),(49902, 25153)
|
||||
(49981, 34876),(49898, 34786)
|
||||
(49957, 43390),(49897, 43384)
|
||||
(49853, 18504),(49848, 18503)
|
||||
(49902, 41752),(49818, 41746)
|
||||
(49907, 30225),(49810, 30158)
|
||||
(49843, 5175),(49808, 5145)
|
||||
(49887, 24274),(49805, 24184)
|
||||
(49847, 7128),(49798, 7067)
|
||||
(49820, 7990),(49771, 7967)
|
||||
(15 rows)
|
||||
|
||||
SELECT * FROM test_cube ORDER BY c~>4 DESC LIMIT 15; -- descending by 2nd coordinate or upper right corner
|
||||
c
|
||||
-------------------------------
|
||||
(36311, 50073),(36258, 49987)
|
||||
(30746, 50040),(30727, 49992)
|
||||
(2168, 50012),(2108, 49914)
|
||||
(21551, 49983),(21492, 49885)
|
||||
(17954, 49975),(17865, 49915)
|
||||
(3531, 49962),(3463, 49934)
|
||||
(19128, 49932),(19112, 49849)
|
||||
(31287, 49923),(31236, 49913)
|
||||
(43925, 49912),(43888, 49878)
|
||||
(29261, 49910),(29247, 49818)
|
||||
(14913, 49873),(14849, 49836)
|
||||
(20007, 49858),(19921, 49778)
|
||||
(38266, 49852),(38233, 49844)
|
||||
(37595, 49849),(37581, 49834)
|
||||
(46151, 49848),(46058, 49830)
|
||||
(15 rows)
|
||||
|
||||
-- same thing for index with points
|
||||
CREATE TABLE test_point(c cube);
|
||||
INSERT INTO test_point(SELECT cube(array[c->1,c->2,c->3,c->4]) FROM test_cube);
|
||||
CREATE INDEX ON test_point USING gist(c);
|
||||
SELECT * FROM test_point ORDER BY c~>1, c~>2 LIMIT 15; -- ascending by 1st then by 2nd coordinate
|
||||
c
|
||||
--------------------------
|
||||
(54, 38679, 3, 38602)
|
||||
(83, 10271, 15, 10265)
|
||||
(122, 46832, 64, 46762)
|
||||
(154, 4019, 138, 3990)
|
||||
(161, 24465, 107, 24374)
|
||||
(162, 26040, 120, 25963)
|
||||
(167, 17214, 92, 17184)
|
||||
(207, 40886, 179, 40879)
|
||||
(259, 1850, 175, 1820)
|
||||
(270, 29508, 264, 29440)
|
||||
(270, 32616, 226, 32607)
|
||||
(288, 49588, 204, 49571)
|
||||
(318, 31489, 235, 31404)
|
||||
(326, 18837, 285, 18817)
|
||||
(337, 455, 240, 359)
|
||||
(15 rows)
|
||||
|
||||
SELECT * FROM test_point ORDER BY c~>4 DESC LIMIT 15; -- descending by 1st coordinate
|
||||
c
|
||||
------------------------------
|
||||
(30746, 50040, 30727, 49992)
|
||||
(36311, 50073, 36258, 49987)
|
||||
(3531, 49962, 3463, 49934)
|
||||
(17954, 49975, 17865, 49915)
|
||||
(2168, 50012, 2108, 49914)
|
||||
(31287, 49923, 31236, 49913)
|
||||
(21551, 49983, 21492, 49885)
|
||||
(43925, 49912, 43888, 49878)
|
||||
(19128, 49932, 19112, 49849)
|
||||
(38266, 49852, 38233, 49844)
|
||||
(14913, 49873, 14849, 49836)
|
||||
(37595, 49849, 37581, 49834)
|
||||
(46151, 49848, 46058, 49830)
|
||||
(29261, 49910, 29247, 49818)
|
||||
(19233, 49824, 19185, 49794)
|
||||
(15 rows)
|
||||
|
||||
|
Reference in New Issue
Block a user