Все ли запросы должны быть в словаре?
Нет. Потому что только начальные слова (в соответствии с используемой конфигурацией текстового поиска ) находятся в индексе для начала. Но что более важно:
Нет . Потому что поверх этого полнотекстового поиска также возможно сопоставление префиксов :
Это будет работать:
SELECT id, subject
FROM mailboxes
WHERE tsv @@ to_tsquery('simple', 'avail:*')
ORDER BY id DESC;
Обратите внимание на 3 вещи:
Используйте to_tsquery()
, а не plainto_tsquery()
в этом случае, потому что ( цитируя руководство ):
... plainto_tsquery
не будет распознавать tsquery
операторы, метки веса или метки совпадения префиксов при вводе
Используйте 'simple'
конфигурацию текстового поиска, чтобы сгенерировать оператор, tsquery
поскольку вы, очевидно, хотите принять слово «все» как есть и не применять stemming.
Добавить, :*
чтобы сделать поиск по префиксу, то есть найти все лексемы, начинающиеся с «польза».
Важно: это префикс поиска по лексемам (основам слов) в документе. Соответствие регулярному выражению без подстановочных знаков ( content ~* 'avail'
) не совсем то же самое! Последний не привязан слева (к началу лексем) и также может найти «FOOavail» и т. Д.
Неясно, хотите ли вы описать поведение в своем запросе или эквивалент добавленного регулярного выражения. Индексы триграмм ( pg_trgm
), например, уже предложенные @Evan, являются подходящим инструментом для этого. На dba.SE много связанных вопросов, попробуйте поиск .
Обзор:
демонстрация
SELECT *
FROM (
VALUES
('Zend has no framework')
, ('Zend Framework')
) sub(t), to_tsvector(t) AS tsv
WHERE tsv @@ to_tsquery('zend <-> fram:*');
id | t | tsv
----+----------------+------------------------
2 | Zend Framework | 'framework':2 'zend':1
Недавний связанный ответ (глава Другой подход к оптимизации поиска ):
Электронные письма?
Поскольку вы упомянули электронные письма, имейте в виду, что анализатор текстового поиска идентифицирует электронные письма и не разделяет их на отдельные слова / лексемы. Рассмотреть возможность:
SELECT ts_debug('english', 'xangr@some.domain.com')
(email,"Email address",xangr@some.domain.com,{simple},simple,{xangr@some.domain.com})
Я бы заменил разделители @
и .
в ваших письмах пробелом ( ' '
) для индексации содержащихся слов.
Кроме того, поскольку вы имеете дело с именами в электронных письмах, а не с английскими (или некоторыми другими языками) словами , я бы использовал 'simple'
конфигурацию текстового поиска, чтобы отключить основание и другие языковые функции:
Постройте ts_vector
колонку с помощью:
SELECT to_tsvector('simple', translate('joe.xangr@some.domain.com', '@.', ' ')) AS tsv;
:*
задокументировано, и 2) разве упоминание о сборке не должноto_tsvector('simple'..)
идти рука об руку с инструкциями о том, что для будущих запросов этого tsv потребуется также «простая» конфигурация, чем tsquery? Я думаю, что вы должны уточнить последствия отключения отключения от tsvector / tsquery.0.380ms
. После вашего пути это заняло0.079 ms
.pg_trgm
. FTS быстрее (с меньшим индексом). Вы даже можете объединить оба индекса ...