Настройка обработки документов на FAST

    Одна из задач при интеграции сторонней поисковой машины в систему — это настройка процесса обработки исходных документов (грубо говоря, индексирования). Сложность настройки такого процесса зависит от функциональных требований к системе поиска и возможностей поисковой машины. Настройка может как ограничиться парой кликов в админке поисковой машины, так и вылиться в написание собственных процедур, скриптов и т.д. Если стандартным возможностям системы (тем более если ее код не может быть модифицирован) мы привыкли доверять, то для собственных скриптов хотелось бы иметь тесты, реализация которых не всегда предусмотрена движком.

    Мы столкнулись с необходимостью реализации поиска на платформе MS FAST ESP 5.3. Этот серьезный движок имеет внушительные возможности кастомизации обработки документов, некоторые из которых мы затронули в своем проекте. В-общем-то, мы хотим поделиться нашим способом тестирования кастомных стейджей на этом движке.

    Документация достаточно хорошо описывает процесс создания стейджей. Мы не будем ее пересказывать, ограничимся лишь сведениями, необходимыми для понимания изложенного.
    В терминологии FAST ESP вся последовательность действий, которая должна быть выполнена при индексировании одного документа, называется Pipeline, а отдельные действия — Stage. Stage запускается в определенном контексте, с которым может взаимодействовать, одним из элементов которого является документ. К примеру, stage может считывать и записывать атрибуты обрабатываемого документа. Схематично весь процесс обработки документов выглядит так:



    Стейдж представлен в виде двух файлов — xml-спецификации и реализации (в FAST ESP 5.3 реализация предусматривает использование языка python v.2.3).

    Ниже пример стейджа, который записывает в поле quality значение 500, если атрибут документа hotornew имеет значение true.
    <processors>
     <processor>
      <load module="processors.SetOnEqual" class="SetOnEqual"/>
      <desc>Set high rank to documents, which have HotOrNew = yes
      </desc>
      <config>
            <param name="Input" value="hotornew" type="str" />
            <param name="Output" value="quality" type="str" />
            <param name="InputFieldValue" value="true" type="str" />
            <param name="OutputFieldValue" value="500" type="int" />
            
      </config>
      <ops>
        <add/>
      </ops>
     </processor>
    </processors>
    

    (спецификация непосредственно в тестах не участвует, приведена для целостности картинки)

    from docproc import Processor, DocumentException,  ProcessorStatus
    
    
    class SetOnEqual(Processor.Processor): 
    
        def ConfigurationChanged(self, attributes): 
            self.input = self.GetParameter('Input') 
            self.output = self.GetParameter('Output') 
            self.inputfieldvalue = self.GetParameter('InputFieldValue')
            self.outputfieldvalue = self.GetParameter('OutputFieldValue')  
       
        def Process(self, docid, document): 
            testField = str(document.GetValue(self.input, None))
            if testField == str(self.inputfieldvalue):
                output = int(self.outputfieldvalue)
                document.Set(self.output,output)
            else:
                    document.Set(self.output, 0)
           
            return ProcessorStatus.OK
    

    Для того, чтобы проверить работу созданного стейджа в родном контексте обработки документа, необходимо проделать последовательность действий, указанную в документации:
    1. Выложить в определенные каталоги файлы спецификации и реализации;
    2. Перезапустить службу обработки документов — Document Processor (procserver. при запуске он компилирует код стейджей);
    3. Включить новый стейдж в pipeline;
    4. Проиндексировать тестовый документ;
    5. Посмотреть на результат обработки документа (можно вывести в лог-файл, а можно “найти” новый документ через стандартный фронтенд и посмотреть все атрибуты документа).

    В случае, если мы не получили ожидаемого результата (к примеру в документе выставили поле hotornew = true, a значение поля Quality так и не изменилось), нам придется заняться отладкой, что означает:
    — Поискать ошибку в логе procserver’a;
    — Проконтролировать, сделал ли конкретно наш стейдж то, что от него просили, поставив стейджи Spy до и после выполнения тестируемого стейджа. (Spy выгружает дамп документа вместе с его атрибутами в файл на диске);
    — Поискать ошибку в коде стейджа.

    После того как ошибка поправлена, нужно опять проверить — т.е. опять выполнить шаги 1, 2, 4, 5.
    Это муторно. Удобнее отлаживать код стейджа “как есть” привычными методами, например в unit-тесте:



    Поэтому для “воссоздания” контекста мы сделали примитивные моки классов, с объектами которых работает стейдж:

    class Document(object):
        """
        Mock сущности Document
        """
        
        def GetValue(self, name, default):
            return getattr(self, name, default)
        
        def Set(self, field, value):
            setattr(self, field, str(value))
    
    
    class Processor (object):
        """
        Mock сущности Processor
        """
    
        def GetParameter(self, name):
            return getattr(self, name)
    
        def Set(self, field, value):
            setattr(self, field, str(value))
    

    В реальности сущность document предоставляет и другие методы. Мы ограничились теми, что используем.
    Теперь можно писать/отлаживать/тестировать стейдж без поискового движка:

    import unittest
    import docproc.Processor as proclib
    from docproc import ProcessorStatus
    import SetOnEqual
    
    class testSetOnEqual(unittest.TestCase):
       
        def setUp(self):
            self.stage = SetOnEqual.SetOnEqual()
            self.stage.Set('Input', 'hot')
            self.stage.Set('Output', 'quality')
            self.assertEquals(self.stage.GetParameter('Input'), 'hot')
            self.assertEquals(self.stage.GetParameter('Output'), 'quality')
          
        def test_true(self):
            self.stage.Set('InputFieldValue', 'true')
            self.stage.Set('OutputFieldValue', '600')
            doc = proclib.Document()
            doc.Set('hot', 'true')        
    
            self.stage.ConfigurationChanged('')
            status = self.stage.Process("docid", doc)
            self.assertEquals(status, ProcessorStatus.OK)
            self.assertEquals(doc.GetValue('quality', ""), '600')
            
        def test_false(self):
            self.stage.Set('InputFieldValue', 'true')
            self.stage.Set('OutputFieldValue', '600')
            doc = proclib.Document()
            doc.Set('hot', 'no')        
    
            self.stage.ConfigurationChanged('')
            status = self.stage.Process("docid", doc)
            self.assertEquals(status, ProcessorStatus.OK)
            self.assertEquals(doc.GetValue('quality', ""), '0')
            
            
    def suite():
    
        suite = unittest.TestSuite()
        suite.addTest(unittest.makeSuite(testSetOnEqual))
        return suite
    
        
    if __name__ == "__main__":
       unittest.main()
    

    Код целиком есть в архиве.

    Что нам дал такой подход:
    — Упрощение жизни себе (здорово экономит время и позволяет не отходить от практики модульного тестирования);
    — Упрощение жизни тестировщику.

    Автор:
    Лия Шабакаева
    Ведущий разработчик
    Департамент разработки Softline
    Softline
    Компания

    Комментарии 3

      0
      Почему fast? Майкрософт же его больше не девелопит и разработка прекращена, а сам он достаточно бажный, если я правильно помню до недавнего времени был еще и платный. Мы переходим на solr.
        0
        Речь идет о подходе к разработке, а не о движке. Движок не заборшен, а переносится на другую платформу. Патчи к предыдущим версиям выпускаются.
        Понравился набор фич «из коробки» — поддержка более 80 языков, практически готовая админка для управления движком (процесса индексирования, настройки релевантности, бустинг и т.д.).
        На момент выбора платформы fast был наиболее подходящим решением.
          +2
          В последней ESP версии серьезных багов замечено не было. Эта версия дорабатывалась (точнее выпускались патчи) MS до выхода новой версии FAST (FAST Search для Sharepoint). Текущая версия самого ядра не сильно отличается от ESP — все различия в реализованных обертках на .NET и введены дополнительные функции. FAST это система поиска корпоративного уровня, аналогичная GSA (google search appliance). Solr до них по многим параметрам не дотягивает, хотя для большого количества задач он (ну и не только он) будет более предпочтителен чем FAST или GSA.

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

        Самое читаемое