Расширяемость<!--Extensibility--> Анализ текста<!--Text Analysis--> Класс Zend_Search_Lucene_Analysis_Analyzer используется индексатором для разбиения текстовых полей документа на лексемы. Методы Zend_Search_Lucene_Analysis_Analyzer::getDefault() и Zend_Search_Lucene_Analysis_Analyzer::setDefault() используются для получения и установки анализатора по умолчанию. Таким образом, вы можете устанавливать собственный анализатор текста или выбирать его из ряда предопределенных анализаторов: Zend_Search_Lucene_Analysis_Analyzer_Common_Text и Zend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive (по умолчанию). Оба интерпретируют лексему как последовательность букв. Zend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive приводит лексемы к нижнему регистру. Переключение между анализаторами: addDocument($doc);]]> Zend_Search_Lucene_Analysis_Analyzer_Common спроектирован для того, чтобы быть родительским классом для всех анализаторов, определяемых пользователем. В наследующем классе достаточно определить методы reset() и nextToken(), которые берут строку из свойства $_input и возвращают лексемы шаг за шагом (NULL означает конец потока). Метод nextToken() должен использовать метод normalize() для каждой лексемы. Это позволит использовать фильтры лексем с вашим анализатором. Ниже приведен пример пользовательского анализатора, котрорый принимает слова с цифрами как элементы: Собственный анализатор текста<!--Custom text Analyzer.--> _position = 0; } /** * API для разбиения на лексемы * Получение следующей лексемы * Возвращает null, если достигнут конец потока * * @return Zend_Search_Lucene_Analysis_Token|null */ public function nextToken() { if ($this->_input === null) { return null; } while ($this->_position < strlen($this->_input)) { // пропуск пробела while ($this->_position < strlen($this->_input) && !ctype_alnum( $this->_input[$this->_position] )) { $this->_position++; } $termStartPosition = $this->_position; // чтение лексемы while ($this->_position < strlen($this->_input) && ctype_alnum( $this->_input[$this->_position] )) { $this->_position++; } // Пустая лексема, конец потока if ($this->_position == $termStartPosition) { return null; } $token = new Zend_Search_Lucene_Analysis_Token( substr($this->_input, $termStartPosition, $this->_position - $termStartPosition), $termStartPosition, $this->_position); $token = $this->normalize($token); if ($token !== null) { return $token; } // Продолжение, если лексема пропущена } return null; } } Zend_Search_Lucene_Analysis_Analyzer::setDefault( new My_Analyzer());]]> Фильтрация лексем<!--Tokens Filtering--> Анализатор Zend_Search_Lucene_Analysis_Analyzer_Common также предоставляет механизм фильтрации лексем. Класс Zend_Search_Lucene_Analysis_TokenFilter является уровнем абстракции для таких фильтров. Он должен использоваться как предок для ваших собственных фильтров. Пользовательские фильтры должны реализовать метод normalize(), который может преобразовывать лексему или сигнализировать, что лексема должна быть пропущена. В предоставляемом анализаторе уже определены три фильтра: Zend_Search_Lucene_Analysis_TokenFilter_LowerCase Zend_Search_Lucene_Analysis_TokenFilter_ShortWords Zend_Search_Lucene_Analysis_TokenFilter_StopWords Фильтр LowerCase уже используется для анализатора Zend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive, который применяется по умолчанию. ShortWords и StopWords могут использоваться с уже включенными анализаторами или вашими собственными: addFilter($stopWordsFilter); Zend_Search_Lucene_Analysis_Analyzer::setDefault($analyzer);]]> addFilter($shortWordsFilter); Zend_Search_Lucene_Analysis_Analyzer::setDefault($analyzer);]]> Конструктор Zend_Search_Lucene_Analysis_TokenFilter_StopWords принимает массив стоп-слов в качестве аргумента. Но стоп-слова можно также загружать и из файла: loadFromFile($my_stopwords_file); $analyzer = new Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum_CaseInsensitive(); $analyzer->addFilter($stopWordsFilter); Zend_Search_Lucene_Analysis_Analyzer::setDefault($analyzer);]]> Файл должен быть текстовым с одним словом в каждой строке. Символом '#' помечаются строки с комментариями. Конструктор Zend_Search_Lucene_Analysis_TokenFilter_ShortWords имеет один необязательный параметр, это ограничение длины слова. Его значение по умолчанию равно 2. Алгоритмы ранжирования<!--Scoring Algorithms--> Ранг q документа d определяется следующим образом: score(q,d) = sum( tf(t in d) * idf(t) * getBoost(t.field in d) * lengthNorm(t.field in d) ) * coord(q,d) * queryNorm(q) tf(t in d) - Zend_Search_Lucene_Search_Similarity::tf($freq) - коэффициент ранга, основанный на том, насколько часто встречается элемент или фраза в документе. idf(t) - Zend_Search_Lucene_Search_SimilaritySimilarity::tf($term, $reader) - коэффициент ранга для простого элемента применительно к определенному индексу. getBoost(t.field in d) - коэффициент усиления для поля элемента. lengthNorm($term) - значение нормализации для поля, получаемое из общего количества элементов, содержащихся в поле. Это значение хранится внутри индекса. Эти значения вместе с коэффициентом усиления поля хранятся в индексе, результатом их умножения является ранг для каждого поля. Совпадения в длинных полях менее точны, поэтому реализации этого метода обычно возвращают тем меньшие значения, чем больше число лексем, и тем большие значения, чем меньше число лексем. сoord(q,d) - Zend_Search_Lucene_Search_Similarity::coord($overlap, $maxOverlap) - коэффициент ранга, основанный на относительной доле всех элементов запроса, найденных в документе. Присутствие большого количества элементов запроса означает лучшее соответствие запросу, поэтому реализации этого метода обычно возвращают бОльшие значения, когда соотношение между этими параметрами большое и меньшие значения, когда соотношение между ними небольшое. queryNorm(q) - значение нормализации для запроса, получаемое из суммы возведенных в квадрат весов каждого из элементов запроса. Это значение затем умножается в вес каждого элемента запроса. Это не влияет на ранжирование, цель нормализации состоит в том, чтобы сделать соизмеримыми ранги, полученные при различных запросах. Алгоритм ранжирования может быть изменен через определение своего собственного класса. Для этого надо создать потомка класса Zend_Search_Lucene_Search_Similarity, как показано ниже, затем использовать метод Zend_Search_Lucene_Search_Similarity::setDefault($similarity); для установки объекта как используемого по умолчанию. ]]> Контейнеры хранения<!--Storage Containers--> Абстрактный класс Zend_Search_Lucene_Storage_Directory определяет функционал директории. Конструктор Zend_Search_Lucene использует строку или объект Zend_Search_Lucene_Storage_Directory как входные данные. Zend_Search_Lucene_Storage_Directory_Filesystem реализует функционал директории для файловой системы. Если для конструктора Zend_Search_Lucene в качестве входных данных испольуется строка, то считыватель индекса (объект Zend_Search_Lucene) рассматривает ее как путь в файловой системе и сама инстанцирует объекты Zend_Search_Lucene_Storage_Directory_Filesystem. Вы можете определить собственную реализацию директории, создав потомка класса Zend_Search_Lucene_Storage_Directory. Методы Zend_Search_Lucene_Storage_Directory: ]]> Метод getFileObject($filename) класса Zend_Search_Lucene_Storage_Directory возвращает объект Zend_Search_Lucene_Storage_File. Абстрактный класс Zend_Search_Lucene_Storage_File реализует абстракцию файла и примитивы чтения файла индекса. Вы должны создать класс, наследующий от Zend_Search_Lucene_Storage_File для своей реализации директории. Только два метода класса Zend_Search_Lucene_Storage_File должны быть перегружены в вашей реализации: ]]>