×
Мы обрабатываем cookies, чтобы сделать наш сайт удобнее и персонализированнее для вас. Подробнее: политика использования «cookies» и «политики конфиденциальности».

Для самостоятельной настройки ознакомьтесь с инструкцией

Дополнительные настройки cookies в браузерах

Файлы cookie автоматически загружаются в ваш браузер при посещении веб-сайта. У вас есть возможность управлять этими файлами. Если Вы не согласны с использованием файлов cookies, запретите их сохранение на своём устройстве, удалите уже имеющиеся файлы cookies через настройки браузера или прекратите использование сайта.

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

Инструкция по отключению cookies
Принять
Настроить
Отклонить

ДОКУМЕНТАЦИЯ

Выберите версию, форк и язык для СУБД Digital Q.DataBase, чтобы прочитать или скачать всю документацию.
Техподдержка
Документация
Диасофт
Авторские права © 2016–2025 ООО "Диасофт Экосистема"
Скачать всю документацию:

2.9.3. Управление текстовым поиском

2.9.3.1. Парсинг документов
2.9.3.2. Разбор запросов
2.9.3.3. Ранжирование результатов поиска
2.9.3.4. Подсветка результатов

Для реализации полнотекстового поиска необходима функция для создания tsvector из документа и tsquery из пользовательского запроса. Кроме того, результаты должны возвращаться в удобном для использования порядке, что требует наличия функции для ранжирования документов по их релевантности поисковому запросу. Также важно обеспечить наглядное отображение результатов поиска. Digital Q.DataBase обеспечивает поддержку всех этих функций.

2.9.3.1. Парсинг документов #

Digital Q.DataBase предоставляет функцию to_tsvector для преобразования документа в tsvector тип данных.

to_tsvector([ config regconfig, ] документ текстовые) возвращает tsvector

to_tsvector выполняет разбор текстового документа на токены, преобразует полученные токены в лексемы и возвращает tsvector , в котором перечисляются лексемы вместе с их позициями в документе. Обработка документа осуществляется в соответствии с заданной конфигурацией текстового поиска или конфигурацией по умолчанию. Ниже приведен простой пример:

SELECT to_tsvector('english', 'a fat  cat sat on a mat - it ate a fat rats');
                  to_tsvector
-----------------------------------------------------
 'ate':9 'cat':3 'fat':2,11 'mat':7 'rat':12 'sat':4

В приведенном выше примере видно, что результирующий объект tsvector не содержит слова a, on, или it, слово rats преобразовалось в rat, а знак пунктуации - был проигнорирован.

Оператор to_tsvector функция внутренне вызывает парсер, который разбивает текст документа на токены и присваивает каждому токену определенный тип. Для каждого токена опрашивается список словарей (Раздел 2.9.6) выполняется обращение к списку, состав которого может меняться в зависимости от типа токена. Первый словарь, который распознает токен, возвращает один или несколько нормализованных токенов лексемы для представления исходного токена. Например, rats преобразовалось в rat так как один из словарей определил, что слово rats является формой множественного числа слова rat. Некоторые слова классифицируются как стоп-слова (Раздел 2.9.6.1), вследствие чего они игнорируются, так как встречаются слишком часто и не несут смысловой нагрузки при поиске. В данном примере это a, on, а также it. Если ни один словарь из списка не распознает токен, он также отбрасывается. В данном примере это произошло со знаком пунктуации - , поскольку для данного типа токенов не назначено ни одного словаря (Пробельные символы), что означает, что пробельные символы никогда не будут индексироваться. Выбор парсера, словарей и типов индексируемых токенов определяется выбранной конфигурацией текстового поиска (Раздел 2.9.7). В рамках одной базы данных может существовать множество различных конфигураций; также доступны стандартные конфигурации для различных языков. В данном примере использовалась конфигурация по умолчанию english для английского языка.

Функция setweight может использоваться для назначения весовых меток элементам tsvector с заданным вес, где вес обозначается одной из латинских букв A, B, C, или D. Как правило, это применяется для маркировки элементов, относящихся к различным частям документа (например, для разграничения заголовка и основного текста). В дальнейшем данная информация может быть использована для ранжирования результатов поиска.

Поскольку to_tsvector(NULL) будет возвращать NULL, рекомендуется использовать функцию coalesce в тех случаях, когда поле может содержать значение null. Ниже описан рекомендуемый метод создания tsvector на основе структурированного документа:

UPDATE tt SET ti =
    setweight(to_tsvector(coalesce(title,'')), 'A')    ||
    setweight(to_tsvector(coalesce(keyword,'')), 'B')  ||
    setweight(to_tsvector(coalesce(abstract,'')), 'C') ||
    setweight(to_tsvector(coalesce(body,'')), 'D');

В данном примере для маркировки источника используется функция setweight для маркировки источника каждой лексемы в итоговом результате tsvector, а затем объединяет помеченные элементы tsvector значения с помощью tsvector оператора конкатенации ||. (Раздел 2.9.4.1 содержит подробные сведения об этих операциях.)

2.9.3.2. Разбор запросов #

Digital Q.DataBase предоставляет функции to_tsquery, plainto_tsquery, phraseto_tsquery и websearch_to_tsquery для преобразования запроса в tsquery тип данных. to_tsquery предоставляет доступ к большему набору функций, чем plainto_tsquery или phraseto_tsquery, но более требовательна к синтаксису входных данных. websearch_to_tsquery представляет собой упрощенную версию функции to_tsquery с альтернативным синтаксисом, аналогичным используемому в поисковых системах.

to_tsquery([ config regconfig, ] querytext текстовые) возвращает tsquery

to_tsquery создает tsquery значение из querytext, которое должно состоять из отдельных токенов, разделенных tsquery операторами & (AND), | (OR), ! (NOT) и <-> (FOLLOWED BY), которые могут быть сгруппированы с использованием скобок. Другими словами, входные данные для функции to_tsquery уже должны соответствовать общим правилам tsquery ввода, описанным в Раздел 2.5.11.2. Разница заключается в том, что если при обычном tsquery вводе токены воспринимаются буквально, to_tsquery нормализует каждый токен в лексему с использованием указанной конфигурации или конфигурации по умолчанию, отбрасывая токены, являющиеся стоп-словами согласно данной конфигурации. Например:

SELECT to_tsquery('english', 'The & Fat & Rats');
  to_tsquery
---------------
 'fat' & 'rat'

Как и при базовом tsquery вводе, каждой лексеме могут быть назначены веса для ограничения области поиска только tsvector лексемами с указанными весами. Например:

SELECT to_tsquery('english', 'Fat | Rats:AB');
    to_tsquery
------------------
 'fat' | 'rat':AB

Кроме того, * может быть добавлен к лексеме для указания сопоставления по префиксу:

SELECT to_tsquery('supern:*A & star:A*B');
        to_tsquery
--------------------------
 'supern':*A & 'star':*AB

Такая лексема будет соответствовать любому слову, tsvector который начинается с заданной строки.

to_tsquery также может принимать фразы, заключенные в одинарные кавычки. Это полезно в первую очередь в тех случаях, когда конфигурация включает словарь-тезаурус, который может срабатывать на подобные фразы. В приведенном ниже примере тезаурус содержит правило: сверхновые звезды : sn:

SELECT to_tsquery('''supernovae stars'' & !crab');
  to_tsquery
---------------
 'sn' & !'crab'

Без использования кавычек to_tsquery будет возвращена синтаксическая ошибка для токенов, не разделенных операторами AND, OR или FOLLOWED BY.

plainto_tsquery([ config regconfig, ] querytext текстовые) возвращает tsquery

plainto_tsquery преобразует неформатированный текст querytext в значение типа tsquery tsquery. Текст проходит синтаксический анализ и нормализацию практически так же, как и для to_tsvector, после чего оператор & (AND) tsquery вставляется между оставшимися словами.

Пример:

SELECT plainto_tsquery('english', 'The Fat Rats');
 plainto_tsquery
-----------------
 'fat' & 'rat'

Обратите внимание, что функция plainto_tsquery не будет распознавать tsquery логические операторы, метки веса или метки префиксного поиска во входных строках:

SELECT plainto_tsquery('english', 'The Fat & Rats:C');
   plainto_tsquery
---------------------
 'fat' & 'rat' & 'c'

Здесь вся пунктуация из входных данных была отброшена.

phraseto_tsquery([ config regconfig, ] querytext текстовые) возвращает tsquery

phraseto_tsquery работает во многом аналогично plainto_tsquery, за исключением того, что она вставляет оператор <-> оператор FOLLOWED BY между оставшимися словами вместо & оператора (AND). Кроме того, стоп-слова не просто отбрасываются, а учитываются путем вставки <N> операторов, а не <-> операторов. Данная функция полезна при поиске точных последовательностей лексем, поскольку операторы FOLLOWED BY проверяют порядок следования лексем, а не просто наличие всех лексем в тексте.

Пример:

SELECT phraseto_tsquery('english', 'The Fat Rats');
 phraseto_tsquery
------------------
 'fat' <-> 'rat'

Подобно plainto_tsquery, the phraseto_tsquery функция не сможет распознать tsquery логические операторы, метки веса или метки префиксного поиска во входных строках:

SELECT phraseto_tsquery('english', 'The Fat & Rats:C');
      phraseto_tsquery
-----------------------------
 'fat' <-> 'rat' <-> 'c'

websearch_to_tsquery([ config regconfig, ] querytext текстовые) возвращает tsquery

websearch_to_tsquery создает tsquery значение из querytext использование альтернативного синтаксиса, при котором обычный неформатированный текст является допустимым запросом. В отличие от plainto_tsquery и phraseto_tsquery, она также распознает определенные операторы. Более того, данная функция никогда не генерирует синтаксических ошибок, что позволяет использовать необработанный пользовательский ввод для поиска. Поддерживается следующий синтаксис:

  • текст без кавычек: текст, не заключенный в кавычки, будет преобразован в термы, разделенные & операторами, так же, как при обработке функцией plainto_tsquery.

  • "текст в кавычках": текст внутри кавычек будет преобразован в термы, разделенные <-> операторами аналогично обработке функцией phraseto_tsquery.

  • OR: слово «или» будет преобразовано в соответствующий | оператор.

  • -: тире будет преобразовано в соответствующий ! оператор.

Прочие знаки пунктуации игнорируются. Таким образом, подобно plainto_tsquery и phraseto_tsquery, данная websearch_to_tsquery функция не сможет распознать tsquery операторы, весовые метки или метки префиксного сопоставления во входных данных.

Примеры:

SELECT websearch_to_tsquery('english', 'The fat rats');
 websearch_to_tsquery
----------------------
 'fat' & 'rat'
(1 row)

SELECT websearch_to_tsquery('english', '"сверхновые звезды" -crab');
       websearch_to_tsquery
----------------------------------
 'supernova' <-> 'star' & !'crab'
(1 row)

SELECT websearch_to_tsquery('english', '"sad cat" or "fat rat"');
       websearch_to_tsquery
-----------------------------------
 'sad' <-> 'cat' | 'fat' <-> 'rat'
(1 row)

SELECT websearch_to_tsquery('english', 'signal -"segmentation fault"');
         websearch_to_tsquery
---------------------------------------
 'signal' & !( 'segment' <-> 'fault' )
(1 row)

SELECT websearch_to_tsquery('english', '""" )( dummy \\ query <->');
 websearch_to_tsquery
----------------------
 'dummi' & 'queri'
(1 row)

2.9.3.3. Ранжирование результатов поиска #

Ранжирование позволяет оценить степень релевантности документов конкретному запросу, чтобы при наличии множества совпадений наиболее подходящие из них выводились первыми. Digital Q.DataBase предоставляет две встроенные функции ранжирования, которые учитывают лексическую, дистанционную и структурную информацию; то есть они учитывают частоту появления терминов запроса в документе, близость их расположения друг к другу и значимость части документа, в которой они встречаются. Однако понятие релевантности является неопределенным и сильно зависит от специфики приложения. Для различных задач может потребоваться дополнительная информация для ранжирования, например, время изменения документа. Встроенные функции ранжирования приведены лишь в качестве примеров. Вы можете разработать собственные функции ранжирования и/или комбинировать их результаты с дополнительными факторами в соответствии с конкретными требованиями.

В настоящее время доступны две функции ранжирования:

ts_rank([ weights float4[], ] vector tsvector, запросу tsquery [, нормализация integer ]) возвращает float4

Выполняет ранжирование векторов на основе частоты соответствующих лексем.

ts_rank_cd([ weights float4[], ] vector tsvector, запросу tsquery [, нормализация integer ]) возвращает float4

Данная функция вычисляет плотность покрытия при ранжировании для заданного вектора документа и запроса, как описано в работе Кларка, Кормака и Тадхоупа «Relevance Ranking for One to Three Term Queries» в журнале «Information Processing and Management», 1999. Метод плотности покрытия аналогичен ts_rank ранжированию за исключением того, что близость соответствующих лексем друг к другу принимается во внимание.

Для выполнения расчётов данной функции требуется информация о позиционном расположении лексем. Следовательно, она игнорирует любые «очищенные» лексемы в tsvector. Если неочищенные лексемы отсутствуют лексемы во входных данных, результат будет равен нулю. (См. Раздел 2.9.4.1 для получения дополнительной информации о strip функции и позиционной информации в tsvectors.)

Для обеих этих функций необязательный weights аргумент позволяет изменять вес вхождений слов в зависимости от присвоенных им меток. Массивы весов определяют значимость каждой категории слов в следующем порядке:

{D-weight, C-weight, B-weight, A-weight}

Если weights не указаны, используются следующие значения по умолчанию:

{0.1, 0.2, 0.4, 1.0}

Обычно веса используются для выделения слов в определенных частях документа, таких как заголовок или аннотация, чтобы наделить их большей или меньшей значимостью по сравнению со словами в тексте документа.

Поскольку в документе большего объема вероятность встретить искомый термин выше, целесообразно учитывать размер документа: например, документ из ста слов с пятью вхождениями поискового слова, скорее всего, будет более релевантным, чем документ из тысячи слов с тем же количеством вхождений. Обе функции ранжирования принимают целочисленный нормализация параметр, определяющий, должна ли длина документа влиять на его ранг, и каким именно образом. Данный параметр управляет несколькими режимами, представляя собой битовую маску: можно выбрать один или несколько режимов, используя | (например, 2|4).

  • 0 (по умолчанию) — длина документа игнорируется

  • 1 — ранг делится на (1 + логарифм длины документа)

  • 2 — ранг делится на длину документа

  • 4 — ранг делится на среднее гармоническое расстояние между экстентами (данный режим реализован только для ts_rank_cd)

  • 8 — ранг делится на количество уникальных слов в документе

  • 16 — ранг делится на (1 + логарифм количества уникальных слов в документе)

  • 32 — ранг делится на (само значение ранга + 1)

Если указано несколько битовых флагов, соответствующие преобразования применяются в порядке их перечисления.

Важно отметить, что функции ранжирования не используют глобальную информацию, поэтому невозможно выполнить точную нормализацию к диапазону 1% или 100%, как это иногда требуется. Параметр нормализации 32 (rank/(rank+1)) может применяться для приведения всех значений ранга к диапазону от нуля до единицы, однако это изменение является исключительно косметическим и не влияет на порядок следования результатов поиска.

Ниже приведен пример запроса, выбирающего только десять совпадений с наиболее высоким рангом:

SELECT title, ts_rank_cd(textsearch, query) AS rank
FROM apod, to_tsquery('neutrino|(dark & matter)') query
WHERE query @@ textsearch
ORDER BY rank DESC
LIMIT 10;
                     заголовок                     |   ранг
-----------------------------------------------+----------
 Нейтрино на Солнце                          |      3.1
 Нейтринный детектор в Садбери                 |      2.4
 Галактическая темная материя: обзор MACHO          |  2.01317
 Горячий газ и темная материя                       |  1.91171
 Скопление Девы: горячая плазма и темная материя |  1.90953
 В поисках солнечных нейтрино                   |      1.9
 NGC 4650A: странная галактика и темная материя     |  1.85774
 Горячий газ и темная материя                       |   1.6123
 Подледный поиск космических нейтрино              |      1.6
 Слабое линзирование искажает Вселенную            | 0.818218

Тот же пример с использованием нормализованного ранжирования:

SELECT title, ts_rank_cd(textsearch, query, 32 /* rank/(rank+1) */ ) AS rank
FROM apod, to_tsquery('neutrino|(dark & matter)') query
WHERE  query @@ textsearch
ORDER BY rank DESC
LIMIT 10;
                     заголовок                     |        ранг
-----------------------------------------------+-------------------
 Нейтрино в Солнце                          | 0.756097569485493
 Садберийская нейтринная обсерватория                 | 0.705882361190954
 Галактическая темная материя в представлении проекта MACHO          | 0.668123210574724
 Горячий газ и темная материя                       |  0.65655958650282
 Скопление Девы: горячая плазма и темная материя | 0.656301290640973
 Сплав за солнечными нейтрино                   | 0.655172410958162
 NGC 4650A: необычная галактика и темная материя     | 0.650072921219637
 Горячий газ и темная материя                       | 0.617195790024749
 Подледная ловля космических нейтрино              | 0.615384618911517
 Слабое линзирование искажает Вселенную            | 0.450010798361481

Ранжирование может быть ресурсозатратной операцией, поскольку оно требует обращения к tsvector каждого соответствующего документа, что может быть ограничено пропускной способностью ввода-вывода и, следовательно, приводить к задержкам. К сожалению, этого почти невозможно избежать, так как реальные запросы часто возвращают большое количество совпадений.

2.9.3.4. Подсветка результатов #

Для представления результатов поиска оптимально отображать фрагмент каждого документа, демонстрирующий его релевантность поисковому запросу. Обычно поисковые системы отображают фрагменты документа с выделенными искомыми терминами. Digital Q.DataBase предоставляет функцию ts_headline которая реализует данную функциональность.

ts_headline([ config regconfig, ] документ текстовые, запросу tsquery [, options текстовые ]) возвращает текстовые

ts_headline принимает документ вместе с запросом и возвращает выдержку из документа, в которой выделены термы из запроса. В частности, функция использует запрос для поиска подходящих фрагментов текста, после чего выделяет все слова, входящие в запрос, даже если их позиции не соответствуют условиям запроса. Конфигурация, используемая для парсинга документа, может быть определена с помощью config; если config параметр опущен, то используется default_text_search_config конфигурация.

Если указана options строка, она должна состоять из разделенного запятыми списка одной или нескольких пар option=value . Доступны следующие параметры:

  • MaxWords, MinWords (целые числа): Данные числа определяют максимальную и минимальную длину выводимых фрагментов (headlines). Значения по умолчанию — 35 и 15.

  • ShortWord (integer): слова указанной длины или короче будут удалены в начале и в конце фрагмента, если только они не являются термами поискового запроса. Значение по умолчанию, равное трем, позволяет исключить распространенные английские артикли.

  • HighlightAll (boolean): если флаг установлен в true, true весь документ будет использован в качестве результирующего фрагмента без учета трех предыдущих параметров. По умолчанию используется значение false.

  • MaxFragments (integer): максимальное количество текстовых фрагментов для отображения. При значении по умолчанию, равном нулю, выбирается метод генерации заголовков без использования фрагментов. Значение больше нуля выбирает метод генерации заголовков на основе фрагментов (см. ниже).

  • StartSel, StopSel (строки): строки, которыми ограничиваются слова запроса, встречающиеся в документе, для их отличия от других слов в выдержке. Значениями по умолчанию являются «» и «», что применимо для вывода в формате HTML.

  • FragmentDelimiter (строка): когда отображается более одного фрагмента, они будут разделены данной строкой. Значение по умолчанию — « ... ».

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

При генерации фрагментов текста (headline) без разделения на части, ts_headline выполняется поиск совпадений для заданного запросу и выбирается один вариант для отображения, при этом предпочтение отдается совпадениям с наибольшим количеством слов из запроса в пределах допустимой длины фрагмента. При генерации фрагментов на основе нескольких частей, ts_headline система находит совпадения с запросом и разделяет каждое из них на «фрагменты» длиной не более MaxWords слов каждый, отдавая предпочтение частям с наибольшим количеством слов из запроса и, по возможности, «дополняя» эти части окружающими словами. Режим генерации на основе фрагментов более эффективен, когда совпадения с запросом распределены по большим разделам документа или когда необходимо отобразить несколько совпадений. В любом из режимов, если совпадения с запросом не обнаружены, будет выведен один фрагмент, состоящий из первых MinWords слова в документе будут отображены.

Пример:

SELECT ts_headline('english',
  'The most common type of search
is to find all documents containing given query terms
and return them in order of their similarity to the
query.',
  to_tsquery('english', 'query & similarity'));
                        ts_headline
------------------------------------------------------------
 содержащие заданные термины запроса                       +
 и возвращать их в порядке их релевантности (сходства) с+
 запросом.

SELECT ts_headline('english',
  'Search terms may occur
many times in a document,
requiring ranking of the search matches to decide which
occurrences to display in the result.',
  to_tsquery('english', 'search & term'),
  'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=<<, StopSel=>>');
                        ts_headline
------------------------------------------------------------
 <> <> могут встречаться                            +
 многократно ... ранжирование найденных совпадений <<поиска>> для определения

ts_headline использует оригинальный документ, а не tsvector краткую сводку, поэтому данная операция может выполняться медленно и должна использоваться с осторожностью.

Наверх
свяжитесь
с нами
контакты
Для прямой связи с нами вы можете использовать контакты ниже, либо оставить заявку через форму обратной связи, и мы обязательно свяжемся с вами

*поля обязательные к заполнению