F.57. rum

F.57.1. Введение
F.57.2. Установка
F.57.3. Общие операторы
F.57.4. Новые классы операторов
F.57.5. Лицензия
F.57.6. Авторы

F.57.1. Введение

Модуль rum предоставляет метод доступа для работы с индексами RUM. Он основан на коде методов доступа GIN.

Индекс GIN позволяет выполнять быстрый полнотекстовый поиск, используя типы tsvector и tsquery, но с таким индексом связан ряд проблем:

  • Медленное ранжирование. Для ранжирования необходима информация о позициях, но в индексе GIN не сохраняется информация о позициях лексем. Поэтому после сканирования индекса необходимо провести ещё одно сканирование собственно данных, чтобы получить позиции лексем.

  • Медленный поиск фраз с индексом GIN. Эта проблема связана с предыдущей, так как для осуществления поиска фраз необходима информация о позициях.

  • Медленное упорядочивание по меткам времени. Индекс GIN не может сохранять вместе с лексемами никакую дополнительную информацию, поэтому это требует дополнительного сканирования данных.

RUM решает эти проблемы, сохраняя дополнительную информацию в дереве идентификаторов. В частности, он сохраняет информацию о позиции лексем или метки времени.

Недостаток RUM состоит в том, что он строится и изменяется медленнее, чем GIN. Это связано с тем, что помимо ключей в индексе сохраняется дополнительная информация, и с тем, что RUM использует унифицированный WAL.

F.57.2. Установка

rum — это обычное расширение Postgres Pro Enterprise без каких-либо особых предварительных требований.

Процедура установки выглядит следующим образом:

$ psql имя_бд -c "CREATE EXTENSION rum"

F.57.3. Общие операторы

Реализованные в модуле rum операторы перечислены в Таблице F.44:

Таблица F.44. Операторы rum

ОператорВозвращаетОписание
tsvector <=> tsqueryfloat4Возвращает расстояние между значениями tsvector и tsquery.
timestamp <=> timestampfloat8Возвращает расстояние между двумя значениями timestamp.
timestamp <=| timestampfloat8Возвращает расстояние только для возрастающих значений timestamp.
timestamp |=> timestampfloat8Возвращает расстояние только для убывающих значений timestamp.

F.57.4. Новые классы операторов

Расширение rum предоставляет следующие классы операторов.

F.57.4.1. rum_tsvector_ops — класс операторов для tsvector

Этот класс операторов сохраняет лексемы tsvector с информацией о позициях. Поддерживает упорядочивание с оператором <=> и поиск по префиксу. Взгляните на следующий пример.

Допустим, у нас есть таблица:

CREATE TABLE test_rum(t text, a tsvector);

CREATE TRIGGER tsvectorupdate
BEFORE UPDATE OR INSERT ON test_rum
FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger('a', 'pg_catalog.english', 't');

INSERT INTO test_rum(t) VALUES ('The situation is most beautiful');
INSERT INTO test_rum(t) VALUES ('It is a beautiful');
INSERT INTO test_rum(t) VALUES ('It looks like a beautiful place');

Чтобы создать индекс rum, необходимо создать расширение:

CREATE EXTENSION rum;

Затем мы можем создать новый индекс:

CREATE INDEX rumidx ON test_rum USING rum (a rum_tsvector_ops);

И выполнять следующие запросы:

SELECT t, a <=> to_tsquery('english', 'beautiful | place') AS rank
    FROM test_rum
    WHERE a @@ to_tsquery('english', 'beautiful | place')
    ORDER BY a <=> to_tsquery('english', 'beautiful | place');
                t                |   rank
---------------------------------+-----------
 The situation is most beautiful | 0.0303964
 It is a beautiful               | 0.0303964
 It looks like a beautiful place | 0.0607927
(3 rows)

SELECT t, a <=> to_tsquery('english', 'place | situation') AS rank
    FROM test_rum
    WHERE a @@ to_tsquery('english', 'place | situation')
    ORDER BY a <=> to_tsquery('english', 'place | situation');
                t                |   rank
---------------------------------+-----------
 The situation is most beautiful | 0.0303964
 It looks like a beautiful place | 0.0303964
(2 rows)

F.57.4.2. rum_tsvector_hash_ops — класс операторов для хешей tsvector

Этот класс операторов сохраняет хеш лексем tsvector с информацией о позиции. Поддерживает упорядочивание с оператором <=>, но не поддерживает поиск по префиксу.

F.57.4.3. rum_timestamp_ops — класс операторов для timestamp

Этот класс операторов обеспечивает быстрый поиск и упорядочивание по полям timestamp. Поддерживает упорядочивание с операторами <=>, <=| и |=>. Может использоваться с классом операторов rum_tsvector_timestamp_ops.

F.57.4.4. rum_timestamptz_ops — класс операторов для timestamptz

Этот класс операторов обеспечивает быстрый поиск и упорядочивание по полям timestamptz. Поддерживает упорядочивание с операторами <=>, <=| и |=>. Может использоваться с классом операторов rum_tsvector_timestamptz_ops.

F.57.4.5. rum_tsvector_timestamp_ops — класс операторов для tsvector с timestamp

Этот класс операторов сохраняет лексемы tsvector с полем timestamp. Взгляните на следующий пример.

Допустим, у нас есть таблица:

CREATE TABLE tsts (id int, t tsvector, d timestamp);

\copy tsts from 'rum/data/tsts.data'

CREATE INDEX tsts_idx ON tsts USING rum (t rum_tsvector_timestamp_ops, d)
    WITH (attach = 'd', to = 't');

С ним мы можем выполнять подобные запросы:

EXPLAIN (costs off)
    SELECT id, d, d <=> '2016-05-16 14:21:25' FROM tsts WHERE t @@ 'wr&qh' ORDER BY d <=> '2016-05-16 14:21:25' LIMIT 5;
                                    QUERY PLAN
-----------------------------------------------------------------------------------
 Limit
   ->  Index Scan using tsts_idx on tsts
         Index Cond: (t @@ '''wr'' & ''qh'''::tsquery)
         Order By: (d <=> 'Mon May 16 14:21:25 2016'::timestamp without time zone)
(4 rows)

SELECT id, d, d <=> '2016-05-16 14:21:25' FROM tsts WHERE t @@ 'wr&qh' ORDER BY d <=> '2016-05-16 14:21:25' LIMIT 5;
 id  |                d                |   ?column?
-----+---------------------------------+---------------
 355 | Mon May 16 14:21:22.326724 2016 |      2.673276
 354 | Mon May 16 13:21:22.326724 2016 |   3602.673276
 371 | Tue May 17 06:21:22.326724 2016 |  57597.326724
 406 | Wed May 18 17:21:22.326724 2016 | 183597.326724
 415 | Thu May 19 02:21:22.326724 2016 | 215997.326724
(5 rows)

F.57.4.6. rum_tsvector_timestamptz_ops — класс операторов для tsvector с timestamptz

См. описание класса операторов rum_tsvector_timestamp_ops.

F.57.4.7. rum_tsvector_hash_timestamp_ops — класс операторов для хешей tsvector

Этот класс операторов сохраняет хеш лексем tsvector с полем timestamp. Не поддерживает поиск по префиксу.

F.57.4.8. rum_tsvector_hash_timestamptz_ops — класс операторов для хешей tsvector

Этот класс операторов сохраняет хеш лексем tsvector с полем timestamptz. Не поддерживает поиск по префиксу.

F.57.4.9. rum_tsquery_ops — класс операторов для tsquery

Сохраняет ветви дерева запроса в дополнительной информации. Например, если у нас есть таблица:

CREATE TABLE query (q tsquery, tag text);

INSERT INTO query VALUES ('supernova & star', 'sn'),
    ('black', 'color'),
    ('big & bang & black & hole', 'bang'),
    ('spiral & galaxy', 'shape'),
    ('black & hole', 'color');

CREATE INDEX query_idx ON query USING rum(q);

Мы можем выполнить следующий быстрый запрос:

SELECT * FROM query
    WHERE to_tsvector('black holes never exists before we think about them') @@ q;
        q         |  tag  
------------------+-------
 'black'          | color
 'black' & 'hole' | color
(2 rows)

F.57.5. Лицензия

Этот модуль распространяется по той же лицензии, что и PostgreSQL.

F.57.6. Авторы

Александр Коротков , Postgres Professional, Россия

Олег Бартунов , Postgres Professional, Россия

Фёдор Сигаев , Postgres Professional, Россия