Быстрый поиск по справочнику или документам

7 2

Проблемы и решение

Проблема первая: в системе DIRECTUM отсутствует полнотекстовый поиск по справочникам, можно лишь открыть этот справочник и при помощи фильтра выбрать нужные записи, но не все реквизиты там отображаются, в том числе и текстовые.

Такой поиск по справочникам есть только в расширениях для Microsoft SharePoint (Мегапоиск), но он очень медленный и не позволяет избавиться от второй проблемы.

Проблема вторая: высокая нагрузка на SQL-сервер затрудняет быстро получить результаты поиска; в свою очередь этот создает еще большую нагрузку.

Возможное решение:

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

Немного о Sphinx

Автор: Андрей Аксенов

Изначально создавалась для БД MySQL, но затем появилась поддержка и MSSQL. Также можно искать по xml-специального вида.

Утилита состоит из двух частей:

1. Индексатор (indexer.exe) - создает индексы по произвольному SQL-запросу или xml и сохраняет их в файл.

2. Сервис (searchd.exe), который осуществляет поиск по этим файлам-индексам.

Sphinx не хранит тексты документов, а лишь только то, что ему нужно для выдачи результатов полнотекстового поиска (не будем вдаваться в подробности). При поиске возвращает только список ИД найденных записей.

Преимущества:

  • Позволяет разгрузить SQL сервер
  • Нет больше никаких SQL-инъекций
  • Высокая скорость индексирования (около 10 Мб/сек (зависит от CPU)) и поиска (~0.1 сек в ~2-4 Гб индексе)
  • Не требуется модификация базы для использования
  • Поиск может вестись с учетом морфологии и (русский и английский стемминг) и созвучности слов (soundex)
  • Есть API для различных языков
  • Горизонтальное масштабирование создания и хранения индекса
  • Есть специальный метод для подсветки найденных слов по переданному тексту

Недостатки:

  • Не умеет использовать Federation Search

Сравнение с аналогами

Тестовые данные: ~3.5M записей, ~5 GB текста (из Wikipedia)

 

MySQL FT

Lucene

Sphinx

Индексация, мин

1627

176

84

Индекс, Мб

3011

6328

2850

Поиск фразы, мсек/запрос

3692

29

21

(данные взяты из презентации с РИТ-2007 «Эффективный полнотекстовый поиск по базам данных»)

Пример использования

Поиск по реквизитам справочника

Например, возьмем справочник «Участия в маркетинговых мероприятиях» (УММ) из модуля «Управление взаимодействием с клиентами». Реквизиты хранятся в таблицах MBAnalit и MBText, но так как в этих полях таблиц могут находиться бинарные данные тип у них image. Отсюда возникает небольшая проблема из-за того, что Sphinx напрямую такие данные использовать не может, поэтому их надо преобразовать в тип text. Делается это стандартными функциями SQL:

CAST(CAST(Tekst as varbinary(8000)) as varchar(8000)) as Tekst

Стало немного лучше, но появилось ограничение, хотя и не очень критичное - максимальная длина текста для создания индекса должна быть меньше 8000 символов (при использовании varchar(max) Sphinx вылетает с ошибкой)

Теперь создадим новый индекс. Для этого потребуется изменить настройки Sphinx: добавить источник информации и задать параметры индекса.

## Источник
source UMM_source
{
	type = mssql

	sql_user = user
	sql_pass = password
	sql_host = host
	sql_db = dbname
	sql_port = 1433
	mssql_winauth = 0 ##Можно использовать win-аутентификацию

	sql_query	= \
select umm.Analit id, umm.NameAn, umm.Dop, CAST(CAST(Tekst as varbinary(8000)) as varchar(8000)) as Tekst \
from MBAnalit umm join MBText on (umm.Analit = MBText.SrcRecID) \
WHERE umm.Vid = ИД аналитики справочника УММ

}

## Индекс
index UMM
{
	source = UMM_source
	path = path_to_index\umm
	morphology = stem_enru
	min_word_len = 2
}

Осталось только запустить утилиту indexer.exe и можно искать.

Поиск по часто используемым документам

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

1. Экспортируем нужные документы в папку

2. Конвертируем их в текстовые файлы (например, бесплатной консольной утилитой Text Mining Tool)

3. Формируем большую xml’ку со всеми документами

4. Изменяем конфигурацию Sphinx

source Docs_source
{
	type = xmlpipe2
	xmlpipe_command = type path_to_xml\1.xml
	xmlpipe_fixup_utf8 = 1
}

index Docs
{
	source = Docs_source
	path = path_to_index\Docs
	morphology = stem_enru
	min_word_len = 2
	charset_type = utf-8
}

5. Запускаем утилиту indexer.exe и пользуемся.

Небольшая статистика:

  • Количество исходных документов (.doc): 145
  • Размер документов (.doc): 16Мб
  • Время конвертации в txt: 1 мин 40 сек
  • Размер конвертируемых файлов: 2,5 Мб
  • Размер xml для создания индекса: 2,6 Мб
  • Время создания индекса: 0,5 сек
  • Размер индекса: 680 кб
  • Время поиска: <0.1 сек

Поиск

  1. Из консоли при помощи утилиты search.exe
  2. Установить службу Sphinx и подключаться к ней при помощи API функций из практически любого языка программирования. Для установки службы надо запустить searchd.exe с параметрами --install --config path_to_config\MY.conf --servicename SphinxSearchServiceName

Например, в компании DIRECTUM был разработан специльзый сайт для поиска по нескольким справочникам и часто используемым документам:

Ссылки

Максим Галимов

Наверное, к недостаткам стоит еще отнести и невозможность коммерческого распространения решений, созданных с использованием Shpinx (идет по GPL).

Михаил Извеков

Зато можно продавать продукт, который умеет интегрироваться с Shpinx. А так же оказывать услуги по внедрению такого решения ;)

P.S. У Shpinx есть и коммерческое лицензирование.

Авторизуйтесь, чтобы написать комментарий