Полигональный словарь polygon (POLYGON) оптимизирован для запросов на проверку вхождения точки в полигон — по сути, для поиска по принципу «обратного геокодирования».
Для заданной координаты (широты/долготы) он эффективно определяет, какой полигон/регион (из множества полигонов, например границ стран или регионов) содержит эту точку.
Он хорошо подходит для сопоставления географических координат с регионом, в который они попадают.
Пример настройки полигонального словаря:
Если вы используете словарь в ClickHouse Cloud, для создания словарей используйте вариант с DDL-запросом, а сам словарь создавайте от имени пользователя default.
Также проверьте список поддерживаемых источников для словарей в руководстве по совместимости с Cloud.
CREATE DICTIONARY polygon_dict_name (
key Array(Array(Array(Array(Float64)))),
name String,
value UInt64
)
PRIMARY KEY key
LAYOUT(POLYGON(STORE_POLYGON_KEY_COLUMN 1))
...
<dictionary>
<structure>
<key>
<attribute>
<name>key</name>
<type>Array(Array(Array(Array(Float64))))</type>
</attribute>
</key>
<attribute>
<name>name</name>
<type>String</type>
<null_value></null_value>
</attribute>
<attribute>
<name>value</name>
<type>UInt64</type>
<null_value>0</null_value>
</attribute>
</structure>
<layout>
<polygon>
<store_polygon_key_column>1</store_polygon_key_column>
</polygon>
</layout>
...
</dictionary>
При настройке полигонального словаря ключ должен быть одного из двух типов:
- Простой полигон. Это массив точек.
- MultiPolygon. Это массив полигонов. Каждый полигон представляет собой двумерный массив точек. Первый элемент этого массива — внешняя граница полигона, а последующие элементы задают области, которые должны быть из него исключены.
Точки можно задавать в виде массива или кортежа координат. В текущей реализации поддерживаются только двумерные точки.
Можно загружать собственные данные во всех форматах, поддерживаемых ClickHouse.
Доступны 3 типа хранилищ в памяти:
| Layout | Описание |
|---|
POLYGON_SIMPLE | Наивная реализация. Для каждого запроса выполняется линейный проход по всем полигонам с проверкой вхождения без дополнительных индексов. |
POLYGON_INDEX_EACH | Для каждого полигона строится отдельный индекс, что в большинстве случаев позволяет быстро проверять вхождение (оптимизировано для географических регионов). На область накладывается сетка, рекурсивно разделяющая ячейки на 16 равных частей. Разделение останавливается, когда глубина рекурсии достигает MAX_DEPTH или ячейка пересекает не более MIN_INTERSECTIONS полигонов. |
POLYGON_INDEX_CELL | Также создаёт описанную выше сетку с теми же параметрами. Для каждой конечной ячейки строится индекс по всем частям полигонов, которые в неё попадают, что позволяет быстро отвечать на запросы. |
POLYGON | Синоним POLYGON_INDEX_CELL. |
Запросы к словарю выполняются с использованием стандартных функций для работы со словарями.
Важное отличие состоит в том, что здесь ключами будут точки, для которых нужно найти содержащий их полигон.
Пример
Пример работы со словарём, определённым выше:
CREATE TABLE points (
x Float64,
y Float64
)
...
SELECT tuple(x, y) AS key, dictGet(dict_name, 'name', key), dictGet(dict_name, 'value', key) FROM points ORDER BY x, y;
В результате выполнения последней команды для каждой точки в таблице ‘points’ будет найден содержащий её многоугольник наименьшей площади, и будут выведены запрошенные атрибуты.
Пример
Вы можете читать столбцы из полигональных словарей с помощью запроса SELECT — для этого просто включите store_polygon_key_column = 1 в конфигурации словаря или соответствующем DDL-запросе.
CREATE TABLE polygons_test_table
(
key Array(Array(Array(Tuple(Float64, Float64)))),
name String
) ENGINE = MergeTree
ORDER BY tuple();
INSERT INTO polygons_test_table VALUES ([[[(3, 1), (0, 1), (0, -1), (3, -1)]]], 'Value');
CREATE DICTIONARY polygons_test_dictionary
(
key Array(Array(Array(Tuple(Float64, Float64)))),
name String
)
PRIMARY KEY key
SOURCE(CLICKHOUSE(TABLE 'polygons_test_table'))
LAYOUT(POLYGON(STORE_POLYGON_KEY_COLUMN 1))
LIFETIME(0);
SELECT * FROM polygons_test_dictionary;
┌─key─────────────────────────────┬─name──┐
│ [[[(3,1),(0,1),(0,-1),(3,-1)]]] │ Value │
└─────────────────────────────────┴───────┘
Последнее изменение 10 июня 2026 г.