ltree. Тип данных для представления меток в иерархической древовидной структуре#
В исходном дистрибутиве установлено по умолчанию: нет.
Связанные компоненты: отсутствуют.
Схема размещения:
ext.
Модуль реализует типы данных ltree, lquery, ltxtquery и представляет:
метки данных в иерархической древовидной структуре;
расширенные средства для поиска в таких деревьях.
Примечание:
Метка — это последовательность алфавитно-цифровых символов и знаков подчеркивания длиной до 256 символов. Примеры:
52,Public_Services.Путь метки — это последовательность из нуля или нескольких разделенных точками меток, представляющая путь от корня иерархического дерева к конкретному узлу. Путь не может содержать больше 65535 меток. Пример:
Level1.Level2.Level3.
Модуль предоставляет следующие типы данных:
ltree– путь метки.lquery– запрос в виде регулярного выражения для поиска нужных значенийltree; в запросе слово выбирает соответствующую метку в заданном пути, а звездочка (*) — ноль или более любых меток.Компоненты запроса можно соединить точками для получения в результате всего пути с указанными метками. Например:
foo # Выбирает путь ровно с одной меткой `foo` *.foo.* # Выбирает путь, содержащий метку `foo` *.foo # Выбирает путь с последней меткой `foo`Для звездочек и слов можно добавить количественное значение, определяющее число меток, которые будут соответствовать этому компоненту. Например:
*{n} # Выбирает ровно `n` меток *{n,} # Выбирает как минимум `n` меток *{n,m} # Выбирает не меньше `n`, но и не более `m` меток *{,m} # Выбирает не больше `m` меток — равнозначно `*{0,m}` foo{n,m} # Выбирает как минимум `n`, но не больше `m` вхождений `foo` foo{,} # Выбирает любое количество вхождений `foo`, в том числе нольСоответствия при отсутствии явного количественного ограничения:
Компонент запроса
Аргумент
Описание
*{,}Любое количество меток
слово{1}Ровно одно вхождение
После элемента
lquery, кроме*, могут быть добавлены модификаторы, которые позволяют выбрать более сложные условия:
@ # Выбирает совпадение без учета регистра; например, запросу `a@` соответствует `A` * # Выбирает любую метку с заданным префиксом, например, запросу `foo*` соответствует `foobar` % # Выбирает в метке начальные слова, разделенные подчеркиваниямиМодификатор
%ищет соответствие по словам, а не по всей метке. Например, запросfoo_bar%выбираетfoo_bar_baz, но неfoo_barbaz. В сочетании с*сопоставление префикса применяется отдельно к каждому слову, например запросfoo_bar%*выбираетfoo1_bar2_baz, но неfoo1_br2_baz.При перечислении нескольких различных меток, отличных от
*, через знак|(ИЛИ), можно выбрать любую из меток. Использованием в начале группы без*знака!(НЕ), можно обозначить необходимость метки, не соответствующей ни одной из списка. Количественное ограничение, если требуется, задается в конце группы, что означает его действие на группу целиком, ограничивая число меток, соответствующих или не соответствующих приведенным в группе.ltxtquery– представляет подобный полнотекстовому запрос поиска подходящих значенийltree. Значениеltxtqueryсодержит слова, возможно с модификаторами@,*,%в конце; эти модификаторы имеют то же значение, что и вlquery. Слова можно объединять символами&(И),|(ИЛИ),!(НЕ) и скобками. Отличается отlqueryтем, чтоltxtqueryвыбирает слова независимо от их положения в пути метки.
Примечание:
ltxtqueryдопускает пробелы между символами.
ltree,lquery— не допускают пробелы между символами.
Для типа ltree определены простые операторы сравнения:
=;<>;<;>;<=;>=.
Сравнение сортирует пути в порядке движения по дереву, а потомки узла сортируются по тексту метки.
Модуль предоставляет специализированные операторы и функции.
Перечень и подробное описание специализированных операторов и функций: https://www.postgresql.org/docs/15/ltree.html#id-1.11.7.32.6
Модуль поддерживает следующие типы индексов для ускорения выполняемых операций:
B-дерево по значениям
ltree:<;<=;=;>=;>.
GiSTпо значениямltree(класс операторовgist_ltree_ops):<;<=;=;>=;>;@>;<@;@;~;?.
GiST-индекс по массивуltree[](класс операторовgist_ltree_ops):ltree[] <@ ltree;ltree @> ltree[];@;~;?.
Подробное описание индексов
ltree: https://www.postgresql.org/docs/15/ltree.html#id-1.11.7.32.7.
Существуют дополнительные расширения, реализующие трансформации типа ltree для языка PL/Python:
Если установить эти трансформации и указать их при создании функции, значения ltree будут отображаться в словаре Python. Обратное преобразование не поддерживается.
Доработка#
Доработка не проводилась.
Ограничения#
Ограничения отсутствуют.
Установка#
Модуль считается «доверенным», поэтому его могут устанавливать пользователи, имеющие право CREATE в текущей базе данных:
CREATE EXTENSION ltree SCHEMA ext;
Внимание!
Расширения, реализующие трансформации, рекомендуется устанавливать в одну схему с
ltree. Другая схема может содержать объекты, созданные злонамеренным пользователем. Выбор такой схемы может повлечь за собой угрозу безопасности во время установки расширения.
Настройка#
Настройка не требуется.
Использование модуля#
Для примера приняты данные из дистрибутива исходного кода – файл contrib/ltree/ltreetest.sql.
Создать таблицу, вставить тестовые данные и создать два индекса:
CREATE TABLE test (path ltree);
INSERT INTO test
VALUES ('Top'),
('Top.Science'),
('Top.Science.Astronomy'),
('Top.Science.Astronomy.Astrophysics'),
('Top.Science.Astronomy.Cosmology'),
('Top.Hobbies'),
('Top.Hobbies.Amateurs_Astronomy'),
('Top.Collections'),
('Top.Collections.Pictures'),
('Top.Collections.Pictures.Astronomy'),
('Top.Collections.Pictures.Astronomy.Stars'),
('Top.Collections.Pictures.Astronomy.Galaxies'),
('Top.Collections.Pictures.Astronomy.Astronauts');
CREATE INDEX path_gist_idx ON test USING GIST (path);
CREATE INDEX path_idx ON test USING BTREE (path);
Результат:
Table "ext.test"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+-------+-----------+----------+---------+----------+--------------+-------------
path | ltree | | | | extended | |
Indexes:
"path_gist_idx" gist (path)
"path_idx" btree (path)
Access method: heap
В итоге мы получаем таблицу test c данными, представляющими следующую иерархию:
Top
/ | \
Science Hobbies Collections
/ | \
Astronomy Amateurs_Astronomy Pictures
/ \ |
Astrophysics Cosmology Astronomy
/ | \
Galaxies Stars Astronauts
Выбор потомков в иерархии наследования:
SELECT path FROM test WHERE path <@ 'Top.Science';
Пример вывода:
path
------------------------------------
Top.Science
Top.Science.Astronomy
Top.Science.Astronomy.Astrophysics
Top.Science.Astronomy.Cosmology
(4 rows)
Примеры выборки по путям:
SELECT path FROM test WHERE path ~ '*.Astronomy.*';
Пример вывода:
path
-----------------------------------------------
Top.Science.Astronomy
Top.Science.Astronomy.Astrophysics
Top.Science.Astronomy.Cosmology
Top.Collections.Pictures.Astronomy
Top.Collections.Pictures.Astronomy.Stars
Top.Collections.Pictures.Astronomy.Galaxies
Top.Collections.Pictures.Astronomy.Astronauts
(7 rows)
SELECT path FROM test WHERE path ~ '*.!pictures@.Astronomy.*';
Пример вывода:
path
------------------------------------
Top.Science.Astronomy
Top.Science.Astronomy.Astrophysics
Top.Science.Astronomy.Cosmology
(3 rows)
Примеры полнотекстового поиска:
SELECT path FROM test WHERE path @ 'Astro*% & !pictures@';
Пример вывода:
path
------------------------------------
Top.Science.Astronomy
Top.Science.Astronomy.Astrophysics
Top.Science.Astronomy.Cosmology
Top.Hobbies.Amateurs_Astronomy
(4 rows)
SELECT path FROM test WHERE path @ 'Astro* & !pictures@';
Пример вывода:
path
------------------------------------
Top.Science.Astronomy
Top.Science.Astronomy.Astrophysics
Top.Science.Astronomy.Cosmology
(3 rows)
Образование пути с помощью функций:
SELECT subpath(path,0,2)||'Space'||subpath(path,2) FROM test WHERE path <@ 'Top.Science.Astronomy';
Пример вывода:
?column?
------------------------------------------
Top.Science.Space.Astronomy
Top.Science.Space.Astronomy.Astrophysics
Top.Science.Space.Astronomy.Cosmology
(3 rows)
Для упрощения процедуры создать функцию SQL, вставляющую метку в определенную позицию в пути:
CREATE FUNCTION ins_label(ltree, int, text) RETURNS ltree
AS 'select subpath($1,0,$2) || $3 || subpath($1,$2);'
LANGUAGE SQL IMMUTABLE;
Использование созданной функции:
SELECT ins_label(path,2,'Space') FROM test WHERE path <@ 'Top.Science.Astronomy';
Пример вывода:
ins_label
------------------------------------------
Top.Science.Space.Astronomy
Top.Science.Space.Astronomy.Astrophysics
Top.Science.Space.Astronomy.Cosmology
(3 rows)
Ссылки на документацию разработчика#
Дополнительно поставляемый модуль ltree: https://www.postgresql.org/docs/15/ltree.html.