Реализация полнотекстового поиска с SoftInform Search SDK

Итак, продолжим разговор о создании приложений с функциями полнотекстового поиска, где данный функционал базируется на возможностях продукта SoftInform Search SDK. Несмотря на то, что мы уже достаточно долго и подробно говорили об этом программном продукте, многое осталось за кадром.

В прошлый раз мы начали разговор о программной работе с поисковыми индексами в SoftInform Search SDK и уже успели узнать, каким образом можно программно создавать новые поисковые индексы; а сегодня поговорим о том, что еще можно сделать с этими самыми индексами с помощью API SoftInform Search SDK.


Открытие индексов

Создавать индексы - это, безусловно, хорошо. Но что делать с теми индексами, которые уже созданы? Правильно, к ним нужно подключаться, иногда удаленно. О том, как это делается при старте работы с SoftInform Search SDK, речь шла еще в самой первой статье, посвященной рассматриваемому программному продукту. Сейчас поговорим немного о другом. О чем именно, думаю, станет понятно после того, как вы изучите листинг 1, в котором как раз и приведен программный код, который отвечает за открытие удаленного индекса.

Листинг 1

 
procedure OpenRemoteIndex;
var
 SiIndex: ISIIndex;
 SiServer: ISIServer;
begin
// Здесь код открытия удалённого сервера
// ...
// Проверяем, есть ли индексы на сервере
 if SiServer.Indexes.Count = 0 then
 begin
   ShowMessage('Данный сервер не содержит индексов.');
 end
 else
 begin
// Выбираем случайный индекс и загружаем его
  Randomize;
  SiIndex := AServer.OpenIndex
   (SiServer.Indexes.IndexName[Random(SiServer.Indexes.Count)]);
  if SiIndex = nil then
   ShowMessage('Индекс открыть не удалось.');
 end;
end;

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

Итак, вначале мы пропустили пару строк кода, отвечающих за подключение к серверу (не совсем пару, но это не слишком существенно).

После того, как соединение с удаленным сервером будет установлено, проверяем, есть ли на этом сервере доступные индексы, которые и будут, с точки зрения нашего приложения, удаленными. Это делается с помощью свойства Indexes интерфейса ISIServer. Если таких индексов на сервере не обнаружено, показываем пользователю сообщение об этом и успокаиваемся. А вот если они там есть, начинается самое интересное.

Мы сначала инициализируем генератор случайных чисел с помощью процедуры Randomize, а затем выбираем индекс со случайным номером из числа имеющихся (само собой, если индекс только один, то номер из случайного становится совсем не случайным). Для открытия удаленного индекса используется метод OpenIndex интерфейса ISIServer, а для получения имени индекса, которое выступает как необходимый параметр для передачи этому методу, - свойство IndexName интерфейса ISIIndex. После выполнения указанного метода проверяем, насколько оно было успешным, путем сравнения с нулевым указателем полученного в результате экземпляра индекса. Соответственно, если индекс был открыт успешно, указатель на него не должен быть нулевым. Если все-таки он оказался именно таким, то мы говорим пользователю о том, что с подключением индекса все не так гладко, как хотелось бы, путем показа соответствующего сообщения во всплывающем диалоговом окне.

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

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


Сервисное обслуживание индексов

То, о чем я сейчас расскажу, сложно назвать как-то иначе, чем "сервисное обслуживание". Дело в том, что поисковые индексы, в которые в достаточно интенсивном режиме постоянно добавляется та или иная информация, нуждаются в определенном обслуживании со стороны того приложения, которое их использует. Что именно включает в себя это обслуживание? Это обновление индекса, его дефрагментация и так называемый анализ индекса. Что ж, давайте сейчас поговорим об этих трех достаточно важных процессах более подробно.

Итак, первым по списку у нас идет обновление индекса. Здесь, наверное, особенно добавить и нечего, потому что обновление - оно, как говорится, и в Африке обновление. Все нужно обновлять, и индексы не исключение, так что давайте сразу взглянем на код, приведенный в листинге 2, а затем обсудим, а что же там, собственно говоря, написано.

Листинг 2

procedure UpdateIndexActionExecute;
var
 AProcess: ISIIndexProcess;
 FIndex: ISIIndex;
begin
 AProcess := FIndex.CreateUpdateProcess;
 if AProcess <> nil then
  AProcess.Start
 else
  ShowMessage('Cannot create index update process');
end;

Здесь комментариев, как видите, нет, поэтому стоит рассказать о назначении каждой строки. Сначала объявляем переменные - конечно, FIndex нужно задавать заранее - путем открытия или создания индекса. Но здесь мы это для простоты восприятия опустили. Первое, что мы должны сделать, - это создать экземпляр процесса обновления индекса, который будет заниматься его обновлением совершенно независимо от дальнейшей логики работы самой запустившей его программы. Как видите, дальше снова выполняем проверку, удалось ли нам, в конце концов, все-таки запустить этот самый процесс. Делается это все, опять-таки, банальным сравнением значения переменной, обозначающей этот процесс, с нулевым указателем.

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

Что касается анализа индекса, то так разработчики из компании SoftInform назвали процесс поиска пересечений и оптимизации индекса, который также позволит увеличить скорость его работы, а также сделает индекс несколько компактнее. Что касается запуска этого процесса, то он реализован точно так же, как и запуск процесса обновления индекса, который мы уже рассмотрели выше при разговоре о коде, представленном в листинге 2. Единственным серьезным отличием является то, что для старта этого процесса вам нужно использовать функцию CreateCrossSimilarAnalyseProcess.

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

Листинг 3

Procedure UpdateStatus;
var
 AProcess: ISIIndexProcess;
 FIndex: ISIIndex;
 s: string;
begin
 if FIndex <> nil then
 begin
  Caption := 'Index: ' + FIndex.IndexFileName;
  AProcess := FIndex.Process;
  if AProcess <> nil then
  begin
   case AProcess.ProcessType of
    siptUpdate:
    begin
     s := 'Index updating...';
    end;
    siptCrossSimilarAnalyse:
    begin
     s := 'Similar analysing...';
    end;
    siptDefragment:
    begin
     s := 'Index defragmenting...';
    end;
    else
     s := 'Unknown index process';
   end;
   StatusBar.SimpleText := s;
  end
  else
   StatusBar.SimpleText := 'Ready';
 end
 else
 begin
  Caption := ' Index: No index';
  StatusBar.SimpleText := 'Ready';
 end;
end;

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


Резюме

Что ж, как видите, ничего такого особенно сложного в работе с индексами в SoftInform Search SDK нет. Конечно, такие вещи, как обновление, дефрагментация и оптимизация индексов, вряд ли имеет смысл оставлять "на откуп" пользователю, поэтому лучше каким-то образом реализовать их выполнение в автоматическом режиме. Но это уже технические детали.

Вадим СТАНКЕВИЧ

Версия для печатиВерсия для печати

Номер: 

25 за 2010 год

Рубрика: 

Software
Заметили ошибку? Выделите ее мышкой и нажмите Ctrl+Enter!