8.11. Типы текстового поиска#

8.11. Типы текстового поиска

8.11. Типы текстового поиска #

Tantor BE предоставляет два типа данных, которые предназначены для поддержки полнотекстового поиска, который представляет собой деятельность поиска по коллекции документов на естественном языке, чтобы найти те, которые наилучшим образом соответствуют запросу. Тип tsvector представляет документ в оптимизированной форме для полнотекстового поиска; тип tsquery аналогично представляет текстовый запрос. Глава 12 предоставляет подробное объяснение этой функциональности, а Раздел 9.13 подводит итоги связанных функций и операторов.

8.11.1. tsvector #

Значение tsvector представляет собой отсортированный список уникальных лексем, которые являются словами, приведенными к нормализованному виду для объединения различных вариантов одного и того же слова (см. Глава 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

Позиция обычно указывает на местоположение исходного слова в документе. Информацию о позиции можно использовать для расчета близости. Значения позиции могут варьироваться от 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

Снова, см. Глава 12 для получения более подробной информации.

8.11.2. tsquery #

Значение tsquery хранит лексемы, которые должны быть найдены, и может объединять их с помощью логических операторов & (И), | (ИЛИ) и ! (НЕ), а также оператора поиска фразы <-> (СЛЕДОВАТЬ ЗА). Также существует вариант оператора СЛЕДОВАТЬ ЗА <N>, где N - это целочисленная константа, которая указывает расстояние между двумя искомыми лексемами. <-> эквивалентен <1>.

Скобки могут использоваться для группировки этих операторов. В отсутствие скобок, ! (НЕ) имеет наивысший приоритет, <-> (СЛЕДОВАТЬ) имеет следующий по приоритету, затем & (И), а | (ИЛИ) имеет наименьший приоритет.

Вот несколько примеров:

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.

Правила цитирования для лексем такие же, как описано ранее для лексем в типе tsvector; и, как и в случае с tsvector, любая необходимая нормализация слов должна быть выполнена перед преобразованием в тип tsquery. Функция to_tsquery удобна для выполнения такой нормализации:

SELECT to_tsquery('Fat:ab & Cats');
    to_tsquery
------------------
 'fat':AB & 'cat'

Обратите внимание, что to_tsquery будет обрабатывать префиксы так же, как и другие слова, что означает, что это сравнение вернет true:

SELECT to_tsvector( 'postgraduate' ) @@ to_tsquery( 'postgres:*' );
 ?column?
----------
 t

потому что postgres преобразуется в postgr:

SELECT to_tsvector( 'postgraduate' ), to_tsquery( 'postgres:*' );
  to_tsvector  | to_tsquery
---------------+------------
 'postgradu':1 | 'postgr':*

который будет соответствовать основной форме postgraduate.