Полнотекстовый поиск по полю hstore с использованием индекса

Можно ли выполнить полнотекстовый поиск в столбце hstore, который использует индекс gin?

У меня есть столбец hstore «данные» и индекс, как говорится в документах:

CREATE INDEX hidx ON testhstore USING GIN (data);

И насколько я могу найти способ сделать запрос по этому поводу, это использовать авалы в столбце hstore:

CAST(avals(data) AS text) @@ 'something'

Однако запрос объяснения выполняет только сканирование, а не поиск по индексу, что занимает несколько секунд в таблице с менее чем 100 тыс. Записями.


person Dan    schedule 22.08.2014    source источник


Ответы (1)


Да, вы можете сделать полнотекстовый индекс для любого выражения, а не только для столбца.

e.g.:

CREATE INDEX someindex ON sometable USING gin(to_tsvector('english', CAST(avals(data) AS text)));

Я рекомендую оборачивать такие выражения в простые функции SQL, например:

CREATE OR REPLACE FUNCTION hstore_vals_text(hstore)
RETURNS text LANGUAGE sql IMMUTABLE AS $$
SELECT CAST(avals($1) AS text);
$$;

CREATE INDEX someindex ON sometable USING gin(to_tsvector('english', hstore_vals_text(data)));

SELECT ... FROM ... WHERE hstore_vals_text(data) @@ to_tsquery('something');

Это помогает синтаксическому анализатору сопоставить индекс с выражением, так как не очень легко выяснить, какие индексы соответствуют каким выражениям.

Для лучшей производительности (за счет неиспользуемого пространства для хранения) вы можете дублировать данные в поддерживаемом триггером столбце, содержащем tsvector, и индексировать его; см. документацию tsearch2, как это сделать. Однако вам нужно написать свой собственный триггер, а не использовать общий.

person Craig Ringer    schedule 22.08.2014
comment
Я получаю ERROR: functions in index expression must be marked IMMUTABLE, когда не использую функцию, но даже при использовании функции запрос объяснения, похоже, не попадает в индекс и все еще выполняет сканирование последовательности. - person Dan; 22.08.2014
comment
avals является неизменяемым, может быть, он возражает против приведения? (смотрит). Очевидно, приведение от text[] к text не является неизменным, что ли? - person Craig Ringer; 22.08.2014
comment
А, postgresql.org/message-id/27130.1323443398@sss. pgh.pa.us . Штопать. Это все усложнит. - person Craig Ringer; 22.08.2014
comment
@Dan Что касается второго, я неправильно написал пример. Исправленный; обратите внимание на обновленный текст запроса. - person Craig Ringer; 22.08.2014
comment
В небольшом наборе данных это произойдет, потому что это быстрее. Для тестирования (только) SET enable_seqscan = off. - person Craig Ringer; 23.08.2014