Документация по PostgreSQL 9.1.1 | ||||
---|---|---|---|---|
Prev | Fast Backward | Chapter 8. Типы данных | Fast Forward | Next |
PostgreSQL предоставляет два типа данных, которые разработаны для поддержки полнотекстового поиска. Поиск производится с помощью коллекции документов на обычном языке, в которых ищутся те документы, которые лучшим образом совпадают с запросом. Тип tsvector представляет собой документ в оптимизированной для поиска форме, а тип tsquery представляет собой некий текстовый запрос. Chapter 12 предоставляет подробный рассказ о полнотекстовом поиске, а Section 9.13 кратко рассказывает о связанных с полнотекстовым поиском функциях и операторах.
Значение tsvector представляет собой сортированный список разных лексем, которые являются словами в нормализованном виде, для объединения разных вариантов одного и того же слова (подробности см. в Chapter 12). Сортировка и удаление дублирующих значений выполняются автоматически при вводе, как показано в данном примере:
SELECT 'a fat cat sat on a mat and ate a fat rat'::tsvector; tsvector ---------------------------------------------------- 'a' 'and' 'ate' 'cat' 'fat' 'mat' 'on' 'rat' 'sat'
Для представления лексем, содержащих пробелы или знаки пунктуации, используются кавычки:
SELECT $$the lexeme ' ' contains spaces$$::tsvector; tsvector ------------------------------------------- ' ' 'contains' 'lexeme' 'spaces' 'the'
(В данном ниже и следующем примерах, используются экранированные долларом строковые литералы, чтобы избежать путаницы с наличием двойных кавычек внутри литералов.) Одинарные кавычки и символы обратной косой черты, используемые в литералах, должны вводится дважды:
SELECT $$the lexeme 'Joe''s' contains a quote$$::tsvector; tsvector ------------------------------------------------ 'Joe''s' 'a' 'contains' 'lexeme' 'quote' 'the'
При желании, для любой или всех лексем можно указать целые числа, указывающие позиции:
SELECT 'a:1 fat:2 cat:3 sat:4 on:5 a:6 mat:7 and:8 ate:9 a:10 fat:11 rat:12'::tsvector; tsvector ------------------------------------------------------------------------------- 'a':1,6,10 'and':8 'ate':9 'cat':3 'fat':2,11 'mat':7 'on':5 'rat':12 'sat':4
Позиция обычно показывает метоположение слова в документе. Информация о позиции может быть использована для вычисления близких (находящихся рядом) слов (англ. термин proximity ranking). Значения позиций могут находится в диапазоне от 1 до 16383; большие значения молча устанавливаются в 16383. Дублирурованные позиции для той же лексемы, отбрасываются.
Лексемам, у которых указаны позиции может затем быть назначен вем, который может иметь значение A, B, C или D. D является значением по умолчанию и поэтому при выводе не показывается:
SELECT 'a:1A fat:2B,4C cat:5D'::tsvector; tsvector ---------------------------- 'a':1A 'cat':5 'fat':2B,4C
Вес обычно используется для отражения структуры документа, например чтобы отличить слова в заголовке от слов в теле документа. Функция определения ранга при поиске текста может назначать разные приоритеты для разных весов.
Это является важным для понимания того, что сам тип tsvector не выполняет никакой нормализации, он просто содержит слова, которые нормализуются нужным образом для того или иного приложения. Например:
select 'The Fat Rats'::tsvector; tsvector -------------------- 'Fat' 'Rats' 'The'
Для большинства приложений, выполняющих поиск текста на английском
языке, данные выше слова не должны считаться нормализованными, но
tsvector этого не знает. Текст сырого документа для
нормализации слов в необходимый для поиск вид, обычно обрабатывается
функцией to_tsvector
:
SELECT to_tsvector('english', 'The Fat Rats'); to_tsvector ----------------- 'fat':2 'rat':3
Подробности, снова см. в Chapter 12.
Любое значение tsquery хранит лексемы, которые предназначены для поиска и комбинируют их, используя логические операторы & (И), | (ИЛИ) и ! (НЕ). Для группировки операторов можно использовать круглые скобки
SELECT 'fat & rat'::tsquery; tsquery --------------- 'fat' & 'rat' SELECT 'fat & (rat | cat)'::tsquery; tsquery --------------------------- 'fat' & ( 'rat' | 'cat' ) SELECT 'fat & rat & ! cat'::tsquery; tsquery ------------------------ 'fat' & 'rat' & !'cat'
Без учёта скобок, наибольший приоритет имеет ! (НЕ), затем & (И) и наконец | (ИЛИ).
Опционально, лексемам в tsquery может назначаться одна и более букв с весом, которые ограничивают при поиске совпадение этих лексем только с лексемами в tsvector, имеющими совпадающий вес:
SELECT 'fat:ab & cat'::tsquery; tsquery ------------------ 'fat':AB & 'cat'
Также, лексемам в tsquery может быть назначен специальный символ *, для того, чтобы указать совпадение по префиксу:
SELECT 'super:*'::tsquery; tsquery ----------- 'super':*
Данный запрос будет совпадать с любым словом в tsvector, которое начинается на "super". Обратите внимание, что префиксы сперва обрабатываются конфигурациями поиска текста, что означает, что данное сравнение возвращает истину:
SELECT to_tsvector( 'postgraduate' ) @@ to_tsquery( 'postgres:*' ); ?column? ---------- t (1 row)
потому, что postgres после стемминга станет postgr:
SELECT to_tsquery('postgres:*'); to_tsquery ------------ 'postgr':* (1 row)
что затем приведёт к совпадению с postgraduate.
Правила экранирования для лексем, точно такие же как было описано
выше для лексем в tsvector; как и в tsvector,
любая необходимая нормализация слов должна выполняться перед
преобразованием в тип tsquery. Для выполнения такой
нормализации может подойти функция to_tsquery
:
SELECT to_tsquery('Fat:ab & Cats'); to_tsquery ------------------ 'fat':AB & 'cat'