Полнотекстовый поиск при помощи Oracle Text

Oracle Text - это бесплатная компонента, входящая в состав Oracle Database, предназначенная для создания приложений с использованием полнотекстового поиска. В предыдущих версиях Oracle имела также названия ConText и interMedia Text. Начиная с 11ой версии входит во все редакции СУБД.

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

Oracle Text позволяет строить полнотекстовые индексы 4-ёх типов:

  • CONTEXT - основной тип индекса. Применяется для индексирования содержимого одной или нескольких колонок таблицы;
  • CTXCAT - применяется для индексации небольших текстовых фрагментов, не требует периодической переиндексации;
  • CTXRULE - применяется при создании приложений для классификации документов;
  • CTXXPATH - предназначен для ускорения работы с полями типа XMLType.

Рассмотрим пример создания контекстного полнотекстового индекса по таблице документов docs.

Создадим таблицу документов и наполним ее данными:

create table docs (id number not null, text varchar2(1000) not null);
insert into docs values (1, 'Шла Саша по шоссе и сосала сушку.');
insert into docs values (2, 'London is the capital of The United Kingdom of Great Britain and Northern Ireland.');


Создадим настройки для полнотекстового индекса и выполним его построение:

begin
    ctx_ddl.create_preference('my_wordlist', 'BASIC_WORDLIST');
    ctx_ddl.create_preference('my_lexer', 'AUTO_LEXER');
    ctx_ddl.set_attribute('my_lexer', 'INDEX_STEMS','YES');
end;

create index docs_idx on docs (text) indextype is ctxsys.context parameters ('LEXER my_lexer WORDLIST my_wordlist');


Тестируем построенный индекс:

select * from docs where contains(text, 'саша') > 0;

ID TEXT
1 Шла Саша по шоссе и сосала сушку.

select * from docs where contains(text, '$идти') > 0;

ID TEXT
1 Шла Саша по шоссе и сосала сушку.

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

select * from docs where contains(text, 'united') > 0;

ID TEXT
2 London is the capital of The United Kingdom of Great Britain and Northern Ireland.

select * from docs where contains(text, 'uni%') > 0;

ID TEXT
2 London is the capital of The United Kingdom of Great Britain and Northern Ireland.

Что еще полезного (помимо вышеприведенных поиска с морфологией и поиска по шаблонам) есть в Oracle Text:
  • подстветка искомых слов в найденном - реализуется при помощи процедур CTX_DOC.MARKUP или CTX_DOC.POLICY_MARKUP;
  • поиск с учетом логических выражений (AND, OR, NOT), расстояния между словами (при помощи оператора NEAR);
  • поиск с учетом тезауруса, синонимов, созвучных слов - к сожалению не работает для русского языка;
  • встоенное извлечение текста из документов разных форматов, например MS Word, Excel, Pdf, RTF, HTML и массы других при помощи утилиты cthxh или процедур CTX_DOC.FILTER или CTX_DOC.IFILTER;
  • возможность индексирования документов, расположенных не только в БД, но и на внешних ресурсах, например в файлах ОС или даже в интернет. Реализуется при помощи установки параметра DATASTORE.

Начиная с версии 11.2 Oracle Text позволяет извлекать из текста документов сущности - например, имена и должности персон, названия стран, городов, компаний, url-адреса, почтовые индексы и т.д., с помощью функций пакета ctx_entity, правда пока только для документов на английском языке.