Геометрические типы данных
На текущий момент единственным поддерживаемым Reindexer геометрическим типом является точка на плоскости (в Golang он реализован как [2]float64
или как тип-синоним Point
).
Для работы с точками на плоскости может быть использован индекс типа rtree
.
При создании индекса можно с помощью тегов указать алгоритм, который будет использоваться при его построении.
Возможные значения тегов:
linear
,quadratic
,greene
,rstar
.
Алгоритмы в этом перечне указаны в порядке от оптимизированных для вставки до оптимизированных для поиска.
Однако многое зависит от данных.
Рекомендуется протестировать, какой вариант больше подходит вам.
По умолчанию используется алгоритм rstar
.
Пример создания индекса для работы с двумерными точками:
type Item struct {
id int `reindexer:"id,,pk"`
pointIndexed Point `reindexer:"point_indexed,rtree,linear"`
pointNonIndexed Point `json:"point_non_indexed"`
}
Функции для работы с точками в Reindexer
Точками могут быть столбцы в отдельных или joined-неймспейсах либо фиксированные точки в формате ST_GeomFromText("point(1 -3)")
.
Поиск точек, находящихся в пределах указанного расстояния друг от друга
Для поиска всех точек, расположенных на определенном расстоянии от заданной точки используется функция ST_DWithin(field_name, point, distance)
.
Принимает 3 параметра: первые два — это координаты точек, третий — дистанция.
Пример запроса с условием фильтрации с помощью функции ST_DWithin()
(вернет точки, находящиеся в пределах расстояния 5.0
от точки с координатами (1.0, -3.5)
):
query := db.Query("test_namespace").DWithin("point_indexed", Point{1.0, -3.5}, 5.0)
SELECT * FROM test_namespace WHERE ST_DWithin(point_indexed, ST_GeomFromText('point(1 -3.5)'), 5.0)
curl --location --request POST 'http://127.0.0.1:9088/api/v1/db/testdb/query' \
--header 'Content-Type: application/json' \
--data-raw '{
"namespace": "test_namespace",
"type": "select",
"filters": [
{
"op": "and",
"cond": "dwithin",
"field": "point_indexed",
"value": [
[
1,
-3.5
],
5
]
}
]
}'
По умолчанию к найденным точкам не применяется никакая сортировка. Если требуется отсортировать результаты по расстоянию, можно использовать для этого
ST_DWithin
совместно сST_Distance
.
Определение расстояния между двумя точками
Для сортировки по расстоянию между двумя точками используется функция ST_Distance()
, принимающая координаты точек.
Примеры:
Сортировка по расстоянию между точкой из поля location и некоторой фиксированной точкой:
query = db.Query("actors").SortStPointDistance("location", Point{1.0, -3.0}, true)
Сортировка по расстоянию между точкой из поля location и точкой из поля city.center:
query = db.Query("actors").SortStFieldDistance("location", "city.center", true)
Cортировка по расстоянию между точкой из поля location и некоторой фиксированной точкой:
SELECT * FROM actors ORDER BY 'ST_Distance(location, ST_GeomFromText(\'point(1 -3)\'))' ASC
Сортировка по расстоянию между точкой из поля location и точкой из поля city.center:
SELECT * FROM actors ORDER BY 'ST_Distance(location, city.center)' ASC
Cортировка по расстоянию между точкой из поля location и некоторой фиксированной точкой:
curl --location --request POST 'http://127.0.0.1:9088/api/v1/db/testdb/query' \
--header 'Content-Type: application/json' \
--data-raw '{
"namespace": "actors",
"type": "select",
"sort": [
{
"field": "ST_Distance(location, ST_GeomFromText(\"point(1 -3)\"))",
"desc": true
}
]
}'
Сортировка по расстоянию между точкой из поля location и точкой из поля city.center:
curl --location --request POST 'http://127.0.0.1:9088/api/v1/db/testdb/query' \
--header 'Content-Type: application/json' \
--data-raw '{
"namespace": "actors",
"type": "select",
"sort": [
{
"field": "ST_Distance(location, city.center)",
"desc": true
}
]
}'