26. Полнотекстовый поиск

Примечание

Полнотекстовый поиск доступен только в промышленной редакции СУБД РЕД База Данных. Подробнее различия функционала редакций СУБД РЕД База Данных описаны в руководстве администратора в разделе "Редакции СУБД РЕД База Данных 5.0".

В «РЕД База Данных» реализованы средства полнотекстового поиска, которые позволяют очень быстро находить нужную информацию в больших объемах текста. Такой тип поиска предусматривает создание соответствующего полнотекстового индекса. Индекс — это объект, создаваемый системой Lucene на основе анализа содержимого документа, необходимый для организации поиска. Он представляет собой своеобразный словарь упоминаний слов в полях.

Полнотекстовый поиск основан на свободно распространяемой библиотеке Lucene. Эта библиотека предоставляет функции индексирования и поиска, доступ к этим функциям реализуется через API Lucene.

Полнотекстовый поиск позволяет:

  • производить поиск по неточному соответствию — искать требуемую информацию при наличии орфографических ошибок в документе или в запросе;

  • производить морфологический поиск — поиск с учётом морфологии (всех возможных форм слова);

  • производить поиск по нескольким объектам БД (поиск по нескольким столбцам и таблицам).

Поиск может осуществляться по текстовым полям (CHAR, VARCHAR), а также по бинарным и текстовым BLOB-полям. При этом BLOB-поля бинарного типа могут содержать внутри себя документы следующих приложений:

  • Acrobat (pdf);

  • MS Word (doc);

  • MS Excel (xls);

  • Microsoft PowerPoint;

  • RTF;

  • Open Office Writer (odt);

  • Html.

Примечание

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

26.1. Миграция полнотекстового поиска с версии 3.0 на 5.0

После успешной миграции базы данных (подробнее о миграции базы данных см. Руководство администратора глава "Миграции с версии 3.0") для работы полнотекстового поиска необходимо выполнить следующие действия:

  1. В конфигурационном файле plugins.conf добавить плагин FTS:

    Plugin = FTS {
        Module = $(dir_plugins)/fts
        Config = FTS_config
    }
    
    Config = FTS_config {
        JarDirs = $(this)/jar/fts
    }
    
  2. Начиная с РЕД Базы Данных 5 полнотекстовый поиск работает с помощью плагина репликации. В конфигурационном файле replication.conf нужно включить плагин FTS для базы данных с полнотекстовым поиском. Можно указать отдельную базу:

    database = /db/employee.fdb
    {
        plugin = FTS
    }
    

    Или включить для всех баз:

    database
    {
        plugin = FTS
    }
    
  3. Последовательно выполнить скрипты обновления FTS из каталога misc/upgrade/fts.

  4. Запустить процедуру создания полнотекстовых индексов FTS$FULL_REINDEX.

26.2. Настройка сервера для работы полнотекстового поиска

В РЕД Базе Данных в системе полнотекстового поиска используется реализация Lucene на языке Java, поэтому для использования описываемого в этом руководстве функционала необходимо установить JRE не ниже 11.

  1. Настройте параметры взаимодействия сервера «РЕД База Данных» с виртуальной машиной Java с помощью конфигурационного файла plugins.conf, который расположен в корневом каталоге установки сервера. В нем необходимо раскомментировать секции Plugin=JAVA и Config=JAVA_config, а также Plugin = FTS и Config = FTS_config. Если они отсутствуют, то добавить:

    Plugin = FTS {
      Module = $(dir_plugins)/fts
      Config = FTS_config
    }
    
    Config = FTS_config {
      JarDirs = $(this)/jar/fts
    }
    
  2. В firebird.conf установите путь к JDK в JavaHome, например:

    JavaHome = /usr/lib/jvm/java-11-openjdk-amd64
    
  3. Подключитесь к базе данных безопасности java-security.fdb и назначьте права доступа пользователям базы данных, использующим код Java (подробнее см. раздел ). Для этого необходимо пролить скрипт fts_permissions.sql, который находится в папке misc корневом каталоге сервера.

    isql -u sysdba -p masterkey -i /opt/RedDatabase/misc/fts_permissions.sql localhost:/opt/RedDatabase/java-security.fdb
    

    В этом скрипте добавляются разрешения для роли FTS, поэтому при работе с полнотекстовым поиском пользователь должен подключаться с ролью FTS.

    Чтобы назначить права на выполнение любого java-кода в java-security.fdb вставьте такую запись:

    insert into permission values(1,'java.security.AllPermission',null, null);
    

    Предупреждение

    Механизм java-security устарел и будет удален в версии 6.0.

  4. В файле конфигурации firebird.conf или databases.conf укажите пути к Java-библиотекам, которые реализуют функции полнотекстового поиска:

    Classpath = ["$(jar)/fts/*.jar"]
    

    Значения указанные в Classpath в databases.conf добавляются к значениям указанным в firebird.conf. Если список jar для какой-либо базы данных нужно полностью заменить, то нужно использовать опцию OverrideClasspath в databases.conf.

  5. Если для БД необходим отдельный каталог для хранения индексов, тогда в файле конфигурации databases.conf задайте параметр FTSDirectory с необходимым каталогом:

    database.fdb = /path/to/database.fdb
    {
      FTSDirectory = /path/to/custom/fts
    }
    
  6. Начиная с версии Java 18 в jvm.args нужно использовать настройку:

    -Djava.security.manager=allow
    

    Установка этого свойства позволяет разрешить динамическую установку Security Manager. Это необходимо, так как начиная с Java 18 по умолчанию это свойство имеет значение disallow, и JavaEngine может столкнуться с ошибкой.

  7. В jvm.args установите директорию для хранения индекса (по умолчанию /tmp/RDBLuceneIndex/)

    -Dfts.directory=...
    
  8. По умолчанию в fts.directory для БД будет создан каталог (если в databases.conf для БД не задан параметр FTSDirectory), имя которого эквивалентно GUID БД, в котором будут храниться индексы. Если необходимо отключить создание каталога (хранить все индексы в fts.directory), установите параметр fts.disableGUID:

    -Dfts.disableGUID=true
    
  9. Также в jvm.args можно указать параметры для установки максимального размера индексируемого документа fts.max_document_size (по умолчанию установлен максимальный размер 2147483647) и пропуска битых документов fts.skip_corrupted (по умолчанию выключен), например:

    -Dfts.max_document_size=10000
    -Dfts.skip_corrupted=true
    
  10. Для включения многопоточности при переиндексации задайте необходимое количество потоков параметром fts.thread_count в jvm.args. Допустимы значения от 1 до 64. Если параметр не указан, то по умолчанию используется 1 поток.

Безопасность

Одной из наиболее важных особенностей платформы Java является система безопасности, так называемая «песочница». JavaEngine интегрирует механизм безопасности J2SE/JAAS с РЕД Базой Данных, так что права могут быть назначены пользователям базы данных, использующим код Java.

Права доступа пользователей действуют на уровне сервера. Они хранятся в базе данных безопасности java-security.fdb. Эта база содержит следующие таблицы:

Таблицы

Поля

PERMISSION_GROUP

ID, NAME

PERMISSION

PERMISSION_GROUP, CLASS_NAME, ARG1, ARG2

PERMISSION_GROUP_GRANT

PERMISSION_GROUP, DATABASE_PATTERN, GRANTEE_TYPE, GRANTEE_PATTERN

Таблицы PERMISSION_GROUP_GRANT и PERMISSION содержат внешний ключ, ссылающийся на столбец ID таблицы PERMISSION_GROUP.

В таблице PERMISSION есть столбец CLASS_NAME, в котором хранится имя Java класса, предоставляющего доступ к системным ресурсам (см. java.security.Permission), и столбцы ARG1/ARG2, в котором хранятся аргументы, переданные конструктору этого класса.

Таблица PERMISSION_GROUP_GRANT связывает PERMISSION_GROUP с пользователями и ролями РЕД Базы Данных. Эта связь осуществляется с помощью DATABASE_PATTERN и GRANTEE_TYPE/GRANTEE_PATTERN. Шаблоны имеют синтаксис оператора SIMILAR TO с символом экранирования '&'. GRANTEE_TYPE определяет, относится ли GRANTEE_PATTERN к ROLE или USER.

База данных java-security.fdb изначально не пустая, в ней создана группа COMMON с некоторыми полномочиями для всех пользователей всех баз данных (шаблон '%').

Таблица 26.1 Предоставленные по умолчанию права

CLASS_NAME

ARG1

ARG2

java.util.PropertyPermission

file.separator

read

java.util.PropertyPermission

java.version

read

java.util.PropertyPermission

java.vendor

read

java.util.PropertyPermission

java.vendor.url

read

java.util.PropertyPermission

line.separator

read

java.util.PropertyPermission

os.*

read

java.util.PropertyPermission

path.separator

read

java.util.PropertyPermission

jna.encoding

read

java.util.PropertyPermission

jna.profiler.prefix

read

26.3. Служебные объекты для полнотекстового поиска

Для функционирования полнотекстового поиска в базе данных должны присутствовать все необходимые служебные объекты. Для создания этих объектов можно выполнить скрипт инициализации fts.sql, который находится в папке misc корневом каталоге сервера.

isql -u sysdba -p masterkey -i /opt/RedDatabase/misc/fts.sql localhost:/tmp/test_fts.fdb

Служебные домены

В полнотекстовом поиске используются три служебных домена.

Таблица 26.2 Служебные домены

Домен

Тип

Описание

FTS$OBJECT_NAME

VARCHAR(31) CHARACTER SET UNICODE_FSS

Используется для указания имен объектов (индексов, таблиц, полей, триггеров).

FTS$NAME

VARCHAR(255) CHARACTER SET UNICODE_FSS

Используется для указания параметров полнотекстового поиска.

FTS$ROW_ID

CHAR(8) CHARACTER SET OCTETS

Используется для объявления полей, в которых будет использоваться RDB$DB_KEY [1].

FTS$KEY

BLOB

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

Служебные таблицы

В полнотекстовом поиске используются три служебные таблицы.

FTS$INDICES

В служебной таблице FTS$INDICES хранятся метаданные индексов.

Таблица 26.3 Структура таблицы FTS$INDICES

Имя поля

Тип

Описание

FTS$INDEX_NAME

VARCHAR(31) CHARACTER SET UNICODE_FSS

Имя индекса.

FTS$DESCRIPTION

BLOB SUB_TYPE 1 CHARACTER SET UNICODE_FSS

Комментарий к индексу.

FTS$ANALYZER

VARCHAR(255) CHARACTER SET UNICODE_FSS

Служебная информация, имя анализатора.

FTS$INDEX_STATUS

CHAR(1) CHARACTER SET UNICODE_FSS

Статус индекса. Это поле может принимать следующие значения:

'I' inactive – индекс неактивный;

'N' new – индекс создан, требует полное переиндексирование;

'U' needs metadata update – требуется изменение метаданных, триггеров и т.д.;

'D' drop – индекс отмечен к удалению;

'C' complete – для индекса сделаны все изменения в метаданных и он индексируется.

FTS$OCR_DISABLE

BOOLEAN

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

FTS$OCR_LANGUAGE

FTS$NAME

Служебная информация. Устанавливает язык для оптического распознавания изображений.

FTS$INDEX_SEGMENTS

В таблице FTS$INDEX_SEGMENTS хранятся данные о составе (сегментах) индексов — метаданные полей, входящих в индекс.

Таблица 26.4 Структура таблицы FTS$INDEX_SEGMENTS

Имя поля

Тип

Описание

FTS$INDEX_NAME

VARCHAR(31) CHARACTER SET UNICODE_FSS

Имя индекса.

FTS$RELATION_NAME

VARCHAR(31) CHARACTER SET UNICODE_FSS

Индексируемая таблица.

FTS$FIELD_NAME

VARCHAR(31) CHARACTER SET UNICODE_FSS

Индексируемое поле.

FTS$POOL

Таблица FTS$POOL содержит значения ключей полнотекстового индекса FTS$KEY для измененных, но не проиндексированных полей.

Таблица 26.5 Структура таблицы FTS$POOL

Имя поля

Тип

Описание

FTS$KEY

BLOB

Хранит значение ключа для полнотекстового индекса.

FTS$STATUS

SMALLINT

Отображает статус записи. Может принимать три значения:

  • 1 - запись добавлена;

  • 2 - запись изменена;

  • 3 - запись удалена.

Служебные хранимые процедуры

FTS$CREATE_INDEX

Процедура FTS$CREATE_INDEX используется для создания индекса.

Таблица 26.6 Входные параметры процедуры FTS$CREATE_INDEX

Имя поля

Тип

Описание

FTS$INDEX_NAME

VARCHAR(31) CHARACTER SET UNICODE_FSS

Имя индекса.

FTS$ANALYZER

VARCHAR(255) CHARACTER SET UNICODE_FSS

Имя анализатора. Значение по умолчанию Standard [2].

FTS$DESCRIPTION

BLOB

Комментарии к индексу. Значение по умолчанию NULL.

FTS$OCR_DISABLE

BOOLEAN

Отключает оптическое распознавание изображений. Значение по умолчанию false.

FTS$OCR_LANGUAGE

FTS$NAME

Устанавливает языки для оптического распознавания изображений. Значение по умолчанию eng+rus.

Значение входного параметра FTS$ANALYZER определяет, какой тип анализатора будет использоваться при индексации добавляемого поля:

Таблица 26.7 Соответствие имен анализаторов и языков

Имя анализатора

Язык

English

Английский

Standard

Английский

Russian

Русский

German

Немецкий

French

Французский

Czech

Чешский

Brazilian

Бразильский

Chinese

Китайский

Dutch

Голландский

Greek

Греческий

CJK

Китайское письмо

Предупреждение

Корректность результатов поиска напрямую зависит от типа выбранного анализатора

FTS$DROP_INDEX

Для удаления индекса из системы полнотекстового поиска используется процедура FTS$DROP_INDEX.

Таблица 26.8 Входные параметры процедуры FTS$DROP_INDEX

Имя

Тип

Описание

FTS$INDEX_NAME

VARCHAR(31) CHARACTER SET UNICODE_FSS

Имя индекса.

FTS$ADD_FIELD_TO_INDEX

Процедура FTS$ADD_FIELD_TO_INDEX добавляет индексируемое поле в индекс.

Таблица 26.9 Входные параметры процедуры FTS$ADD_FIELD_TO_INDEX

Имя

Тип

Описание

FTS$INDEX_NAME

VARCHAR(31) CHARACTER SET UNICODE_FSS

Имя индекса.

FTS$RELATION_NAME

VARCHAR(31) CHARACTER SET UNICODE_FSS

Индексируемая таблица.

FTS$FIELD_NAME

VARCHAR(31) CHARACTER SET UNICODE_FSS

Индексируемое поле.

FTS$DROP_FIELD_FROM_INDEX

Процедура FTS$DROP_FIELD_FROM_INDEX используется для удаления индексируемого поля из индекса.

Таблица 26.10 Входные параметры процедуры FTS$DROP_FIELD_FROM_INDEX

Имя

Тип

Описание

FTS$INDEX_NAME

VARCHAR(31) CHARACTER SET UNICODE_FSS

Имя индекса.

FTS$RELATION_NAME

VARCHAR(31) CHARACTER SET UNICODE_FSS

Индексируемая таблица.

FTS$FIELD_NAME

VARCHAR(31) CHARACTER SET UNICODE_FSS

Индексируемое поле.

FTS$REINDEX

Служебная процедура FTS$REINDEX производит полную (по всем записям, с заменой ранее существующего индекса) переиндексацию указанного индекса.

Таблица 26.11 Входные параметры процедуры FTS$REINDEX

Имя

Тип

Описание

FTS$INDEX_NAME

VARCHAR(31) CHARACTER SET UNICODE_FSS

Имя индекса.

FTS$SEARCH_ID

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

Входные параметры процедуры FTS$SEARCH_ID такие же, как у FTS$SEARCH.

Таблица 26.14 Выходные параметры процедуры FTS$SEARCH_ID

Имя поля

Тип

Описание

FTS$ROW_ID

BIGINT

Значение первичного ключа.

FTS$SCORE

DOUBLE PRECISION

Оценка соответствия возвращаемой записи условию поиска.

FTS$RELATION

VARCHAR(31) CHARACTER SET UNICODE_FSS

Таблица, в которой найдено поле, удовлетворяющее фильтру.

FTS$HIGHLIGHT

VARCHAR(512)

Фрагмент текста, содержащий строку,удовлетворяющей условиям поиска. Найденная строка заключается в теги <B> </B>.

FTS$SEARCH_JSON

Возвращает BLOB с JSON значением - имя таблицы, имена полей первичных ключей и их значения.

Входные параметры процедуры FTS$SEARCH_JSON такие же, как у FTS$SEARCH.

Таблица 26.15 Выходные параметры процедуры FTS$SEARCH_JSON

Имя поля

Тип

Описание

FTS$ROW_ID

BLOB

JSON значение, содержащее имя таблицы, имена полей первичных ключей и их значения.

FTS$SCORE

DOUBLE PRECISION

Оценка соответствия возвращаемой записи условию поиска.

FTS$RELATION

VARCHAR(31) CHARACTER SET UNICODE_FSS

Таблица, в которой найдено поле, удовлетворяющее фильтру.

FTS$HIGHLIGHT

VARCHAR(512)

Фрагмент текста, содержащий строку,удовлетворяющей условиям поиска. Найденная строка заключается в теги <B> </B>.

FTS$FULL_REINDEX

Для выполнения полной переиндексации для всех индексов, созданных в БД, выполняется процедурой FTS$FULL_REINDEX. Процедура не имеет входных и выходных параметров.

FTS$STARTDAEMON

Запускает демон [3] переиндексации для того, чтобы при изменении индексируемых наборов данных переиндексация выполнялась автоматически. «Демон» выполняет непрерывный (каждые 0,1 с) мониторинг таблицы FTS$POOL и переиндексацию измененных записей, после чего соответствующие записи удаляются из FTS$POOL. Процедура не имеет входных и выходных параметров.

FTS$STOPDAEMON

Останавливает демон переиндексации. Процедура не имеет входных и выходных параметров.

26.4. Пример использования полнотекстового поиска

Допустим в базе данных создана таблица TEST_TABLE:

create table TEST_TABLE(
id int primary key,
str varchar(1024));

Добавим в нее несколько записей:

insert into TEST_TABLE values(0, 'There were photographs of all her children proudly displayed on the mantelpiece.');
insert into TEST_TABLE values(1, 'His trophies were proudly displayed in a backlit cabinet.');
insert into TEST_TABLE values(2, 'Characters in mathematical mode are usually shown in italics, but sometimes especial function names require different formatting, this is accomplished by using operators.');

И попытаемся найти в ней слово 'displayed' полнотекстовым поиском.

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

  1. создание индекса;

  2. добавление/удаление полей в индекс;

  3. выполнение переиндексации;

  4. поиск;

  5. удаление индекса (если необходимо).

Создание индекса

Сначала необходимо создать индекс. Для этого следует выполнить процедуру FTS$CREATE_INDEX, указав необходимые входные параметры. Обязательным входным параметром является только имя индекса. Второй входной параметр позволяет задать тип анализатора. Доступные типы анализаторов приведены в таблице 26.7. По умолчанию используется значение Standard. Значение третьего параметра задает описание для индекса.

EXECUTE PROCEDURE FTS$CREATE_INDEX('TEST_INDEX');

При этом в таблицу FTS$INDICES добавится запись. Значение поля FTS$INDEX_STATUS равно N, что означает, что индекс только что создан, требует полной переиндексации.

Добавление полей в индекс

После того как индекс создан, в него можно добавлять поля из таблиц базы данных. Для добавления поля в индекс используется процедура FTS$ADD_FIELD_TO_INDEX.

Процедура имеет следующие обязательные входные параметры: имя индекса, имя таблицы, имя поля.

EXECUTE PROCEDURE FTS$ADD_FIELD_TO_INDEX('TEST_INDEX', 'TEST_TABLE', 'STR');

После добавления поля в индекс в таблице FTS$INDEX_SEGMENTS должна появиться соответствующая запись.

Удаление полей из индекса

Для удаления полей из индекса в системе полнотекстового писка используется процедура FTS$DROP_FIELD_FROM_INDEX. Процедура имеет три обязательных входных параметра: имя индекса, из состава которого удаляется поле; имя таблицы, которая содержит это поле; имя удаляемого поля.

EXECUTE PROCEDURE FTS$DROP_FIELD_FROM_INDEX('TEST_INDEX','TEST_TABLE','STR');

После удаления поля из состава из таблицы FTS$INDEX_SEGMENTS удалится запись, связывающая поле и индекс.

Переиндексация

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

  • FTS$FULL_REINDEX

  • FTS$REINDEX

  • FTS$STARTDAEMON

Процедура FTS$FULL_REINDEX выполняет полную переиндексацию для всех индексов в системе полнотекстового поиска. Процедура FTS$FULL_REINDEX не имеет входных параметров.

EXECUTE PROCEDURE FTS$FULL_REINDEX;

Процедура FTS$REINDEX позволяет выполнить полную переиндексацию по указанному индексу. Процедура имеет один обязательный входной параметр — имя индекса, например:

EXECUTE PROCEDURE FTS$REINDEX ('TEST_INDEX');

Процедура FTS$STARTDAEMON запускает «демон» переиндексации. «Демон» выполняет каждые 0.1 секунды мониторинг таблицы FTS$POOL. В таблице FTS$POOL сохраняются RDB$DB_KEY изменившихся записей. По значению RDB$DB_KEY «демон» выполняет переиндексацию только изменившихся записей, после чего RDB$DB_KEY переиндексированных записей удаляется из таблицы FTS$POOL. «Демон» следует запускать в отдельном коннекте к базе.

EXECUTE PROCEDURE FTS$STARTDAEMON;

Поиск

Для извлечения данных из индекса в системе полнотекстового поиска используется процедура FTS$SEARCH.

Процедура имеет следующие входные параметры: имя индекса, имя таблицы, фраза поиска и отображаемое количество символов результата поиска. Второй входной параметр – имя индексируемой таблицы может принимать значение NULL, в этом случае поиск выполняется по всем таблицам, входящим в индекс. Если же указано имя индексируемой таблицы, то поиск будет выполняться только по этой таблице.

Выходные параметры процедуры: таблица, в которой найдены данные, удовлетворяющие условию поиска; значение RDB$DB_KEY для найденных записей; значение соответствия найденной записи условию поиска; фрагмент текста с искомой строкой.

Пример поиска слова 'displayed' по всем таблицам в индексе TEST_INDEX, длина фрагмента результата поиска равна 20 символов:

SELECT * from FTS$SEARCH('TEST_INDEX', NULL, 'displayed', 20);

Допустим, что при поиске было найдено две записи, в этом случае результат поиска для приведенного выше примера может иметь вид:

ROW_ID

SCORE

RELATION

HIGHLIGHT

840000000A000000

0.5414568781852722

TEST_TABLE

His trophies were proudly <B>displayed</B>

8400000009000000

0.5178392529487610

TEST_TABLE

<B>displayed</B> on the mantelpiece.

Здесь ROW_ID это значение RDB$DB_KEY найденной записи; SCORE – соответствие найденной записи условию поиска; RELATION – имя таблицы, в которой была найдена запись; HIGHLIGHT – фрагмент текста, содержащий строку, удовлетворяющую условиям поиска.

По значению RDB$DB_KEY можно выбрать непосредственно найденные записи из соответствующих таблиц, например:

SELECT B.* from FTS$SEARCH('TEST_INDEX', NULL, 'displayed', 20) as A
   LEFT JOIN TEST_TABLE as B
      ON A.FTS$ROW_ID = B.RDB$DB_KEY;

Результатом такого запроса в отличие от предыдущего примера будет выборка из таблицы TEST_TABLE, например:

ID

STR

1

His trophies were proudly displayed in a backlit cabinet.

0

There were photographs of all her children proudly displayed on the mantelpiece.

Пример, возвращающий в FTS$ROW_ID JSON значение:

SELECT FTS$ROW_ID, FTS$SCORE, FTS$RELATION, FTS$HIGHLIGHT  
FROM FTS$SEARCH_JSON('TEST_INDEX', NULL, 'displayed', 100);

Результат запроса:

ROW_ID

SCORE

RELATION

HIGHLIGHT

{"data":[{"ID":1}], "table":"TEST_TABLE"}

0.253744274377822

TEST_TABLE

His trophies were proudly <B>displayed</B> in a backlit cabinet.

{"data":[{"ID":0}], "table":"TEST_TABLE"}

0.230805337429046

TEST_TABLE

There were photographs of all her children proudly <B>displayed</B> on the mantelpiece.

Пример, возвращающий в FTS$ROW_ID ID записи таблицы:

SELECT FTS$ROW_ID, FTS$SCORE, FTS$RELATION, FTS$HIGHLIGHT
FROM FTS$SEARCH_ID('TEST_INDEX', NULL, 'displayed', 100);

Результат запроса:

ROW_ID

SCORE

RELATION

HIGHLIGHT

1

0.2537442743778229

TEST_TABLE

His trophies were proudly <B>displayed</B> in a backlit cabinet.

0

0.2308053374290466

TEST_TABLE

There were photographs of all her children proudly <B>displayed</B> on the mantelpiece.

Ошибка, возвращаемая процедурой FTS$SEARCH_ID, когда индекс содержит более одного первичного ключа:

Statement failed, SQLSTATE = HY000
java.sql.SQLException: Table 'TEST_TABLE' has more than 1 field in the primary key
at org.firebirdsql.lucene.query.LuceneResultSet.fetch(LuceneResultSet.java:157)
-At procedure 'FTS$SEARCH_ID'

Индексация изменений в таблице

Для поддержания актуальности полнотекстовых индексов таблиц, задействованных в полнотекстовом поиске, необходимо указать плагин FTS в plugins.conf:

Plugin = FTS {
    Module = $(dir_plugins)/fts
    Config = FTS_config
}

Config = FTS_config {
    JarDirs = $(this)/jar/fts
}

И настроить плагин репликации FTS в конфигурационном файле replication.conf:

database = /examples/empbuild/employee.fdb
{
    plugin = FTS
}

Если на сервере настроена репликация, то для включения полнотекстовой репликации также необходимо указать FTS плагин. К примеру, для мастер-базы настройка будет выглядеть следующим образом:

database = /db/employee.fdb
{
    sync_replica = sysdba:masterkey@localhost:/db/fts_repl.fdb
    plugin = FTS
}

Для базы-реплики также необходимо указать плагин FTS, кроме того, должна быть включена настройка каскадной репликации. Например:

database = /db/fts_repl.fdb
{
    cascade_replication = true
    plugin = FTS
}

Примечание

Для полнотекстовой индексации таблиц необходимо включить репликацию в базе:

ALTER DATABASE ENABLE PUBLICATION;

А также добавить задействованные в полнотекстовом поиске таблицы в публикации:

ALTER DATABASE INCLUDE TABLE TABLE1, TABLE2,... TO PUBLICATION;

Без этого плагин будет неактивен.

Удаление индекса

Для удаления индекса используется процедура FTS$DROP_INDEX, которая имеет один обязательный входной параметр – имя индекса.

EXECUTE PROCEDURE FTS$DROP_INDEX ('TEST_INDEX');

При удалении индекса удаляются:

  • Соответствующая запись из таблицы FTS$INDICES;

  • Связанные с индексом записи из таблицы FTS$INDEX_SEGMENTS;

  • Файлы индекса на диске.

26.5. Синтаксис поисковых запросов

Термы

Поисковые запросы (фразы поиска) состоят из термов и операторов. Lucene поддерживает простые и сложные термы. Простые термы состоят из одного слова, сложные из нескольких. Первые из них, это обычные слова, например, "привет", "тест". Второй же тип термов это группа слов, например, "Привет как дела". Несколько термов можно связывать вместе при помощи логических операторов. Регистр символов неважен.

Маска

Lucene позволяет производить поиск документов по маске, используя в термах символы «?» и «*». В этом случае символ «?» заменяет один любой символ, а «*» - любое количество символов, например:

 'te?t' 
 'test*' 
 'tes*t' 

Предупреждение

Поисковый запрос нельзя начинать с символов «?» или «*».

Нечеткий поиск

Для выполнения нечеткого поиска в конец терма следует добавить тильду «~». В этом случае будут искаться все похожие слова, например при поиске "roam~" будут так же найдены слова "foam" и "roams".

Усиление термов

Lucene позволяет изменять значимость термов во фразе поиска. Например, вы ищете фразу "Hello world" и хотите, чтобы слово «world» было более значимым. Значимость терма во фразе поиска можно увеличить, используя символ «^», после которого указывается коэффициент усиления. В следующем примере значимость слова «world» в четыре раза больше значимости слова «Hello», которая по умолчанию равна единице.

 'Hello world^4' 

Логические операции

Булевы операторы позволяют использовать логические конструкции при задании условий поиска, позволяют комбинировать несколько термов. Lucene поддерживает следующие булевы операторы: AND, +, OR, NOT, -.

Предупреждение

Булевы операторы должны указываться заглавными буквами.

Оператор OR

OR является булевым оператором по умолчанию, это означает, что если между двумя термами фразы поиска не указан другой булев оператор, то подставляется опeрaтоp OR. При этом система поиска находит документ, если одна из указанных во фразе поиска терм в нем присутствует. Альтернативным обозначением оператора OR является «||».

 'Hello world world' 

Эквивалентно:

 'Hello world OR world' 

Оператор AND

Оператор AND указывает на то, что в тексте должны присутствовать все, объединенные оператором термы поиска. Альтернативным обозначением оператора является «&&».

 'Hello AND world' 

Оператор +

Оператор + указывает на то, что следующее за ним слово должно обязательно присутствовать в тексте (после знака + не должно быть пробела). Например, для поиска записей, которые должны содержать слово «hello» и могут содержать слово «world», фраза поиска может иметь вид:

 '+Hello world' 

Оператор NOT

Оператор NOT позволяет исключить из результатов поиска те, в которых встречается терм, следующий за оператором. Вместо слова NOT может использоваться символ «!». Например, для поиска записей, которые должны содержать слово «hello» и не должны содержать слово «world», фраза поиска может иметь вид:

 'Hello NOT world' 

Предупреждение

Оператор NOT не может использоваться только с одним термом. Например, поиск с таким условием не вернет результатов:

 'NOT world' 

Оператор —

Этот оператор является аналогичным оператору NOT. После знака - не должно быть пробела. Пример использования:

 'Hello -world' 

Группировка булевых операторов

Анализатор запросов Lucene поддерживает группировку булевых операторов. Допустим, требуется найти либо слово «word», либо слово «dolly» и обязательно слово «hello», для этого используется такой запрос:

 'Hello && (world || dolly)' 

Экранирование специальных символов

Для включения специальных символов во фразу поиска выполняется их экранирование обратным слешем «\». Ниже приведен список специальных символов, используемых в Lucene на данный момент:

+ - && || ! ( ) { } [ ] ^ " ~ * ? : \

Фраза поиска для выражения \((1 +1):2\) будет иметь вид:

 '\(1\+1\)\:2' 

Более подробное англоязычное описание синтаксиса расположено на официальном сайте Lucene.