Проблемы и решение
Проблема первая: в системе 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 сек
Поиск
- Из консоли при помощи утилиты search.exe
- Установить службу Sphinx и подключаться к ней при помощи API функций из практически любого языка программирования. Для установки службы надо запустить searchd.exe с параметрами --install --config path_to_config\MY.conf --servicename SphinxSearchServiceName
Например, в компании DIRECTUM был разработан специльзый сайт для поиска по нескольким справочникам и часто используемым документам:

Ссылки
- Sphinx можно скачать с официального сайта: http://sphinxsearch.com/
- Text Mining Tool - http://text-mining-tool.com/