Класс 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
приводит лексемы к нижнему регистру.
Переключение между анализаторами:
<?php Zend_Search_Lucene_Analysis_Analyzer::setDefault( new Zend_Search_Lucene_Analysis_Analyzer_Common_Text()); ... $index->addDocument($doc); ?>
Zend_Search_Lucene_Analysis_Analyzer_Common
создан для того,
чтобы быть родительским классом для всех анализаторов,
определяемых пользователем. Пользователь должен определить только метод
tokenize()
, который принимает входные данные в виде строки
и возвращает массив лексем.
Метод tokenize()
должен использовать метод
normalize()
для всех лексем. Он позволит использовать
фильтры лексем с вашим анализатором.
Здесь приведен пример пользовательского анализатора, котрорый принимает слова с цифрами как элементы:
Пример 15.1. Собственный анализатор текста
<?php /** Это созданный пользователем текстовый анализатор, который интерпретирует слова с цифрами как один элемент. */ /** Zend_Search_Lucene_Analysis_Analyzer_Common */ require_once 'Zend/Search/Lucene/Analysis/Analyzer/Common.php'; class My_Analyzer extends Zend_Search_Lucene_Analysis_Analyzer_Common { /** * Разбиение текста на лексемы * Returns array of Zend_Search_Lucene_Analysis_Token objects * * @param string $data * @return array */ public function tokenize($data) { $tokenStream = array(); $position = 0; while ($position < strlen($data)) { // пропуск пробелов while ($position < strlen($data) && !ctype_alpha($data{$position}) && !ctype_digit($data{$position})) { $position++; } $termStartPosition = $position; // чтение лексемы while ($position < strlen($data) && (ctype_alpha($data{$position}) || ctype_digit($data{$position}))) { $position++; } // Пустая лексема, конец потока. if ($position == $termStartPosition) { break; } $token = new Zend_Search_Lucene_Analysis_Token(substr($data, $termStartPosition, $position-$termStartPosition), $termStartPosition, $position); $tokenStream[] = $this->normalize($token); } return $tokenStream; } } Zend_Search_Lucene_Analysis_Analyzer::setDefault( new My_Analyzer()); ?>
Ранг 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);
для установки объекта как используемого по умолчанию.
<?php class MySimilarity extends Zend_Search_Lucene_Search_Similarity { public function lengthNorm($fieldName, $numTerms) { return 1.0/sqrt($numTerms); } public function queryNorm($sumOfSquaredWeights) { return 1.0/sqrt($sumOfSquaredWeights); } public function tf($freq) { return sqrt($freq); } /** * Сейчас не используется. Подсчитывает сумму соответствий неточной фразе, * основанную на изменяемом расстоянии. */ public function sloppyFreq($distance) { return 1.0; } public function idfFreq($docFreq, $numDocs) { return log($numDocs/(float)($docFreq+1)) + 1.0; } public function coord($overlap, $maxOverlap) { return $overlap/(float)$maxOverlap; } } $mySimilarity = new MySimilarity(); Zend_Search_Lucene_Search_Similarity::setDefault($mySimilarity); ?>
Абстрактный класс 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
:
<?php abstract class Zend_Search_Lucene_Storage_Directory { /** * Закрывает средство хранения. * * @return void */ abstract function close(); /** * Создает новый пустой файл с данным именем в директории. * * @param string $name * @return void */ abstract function createFile($filename); /** * Удаляет существующий файл в директории. * * @param string $filename * @return void */ abstract function deleteFile($filename); /** * Возвращает true, если файл с данным именем существует. * * @param string $filename * @return boolean */ abstract function fileExists($filename); /** * Возвращает длину файла в директории. * * @param string $filename * @return integer */ abstract function fileLength($filename); /** * Возвращает время последнего изменения файла в формате UNIX. * * @param string $filename * @return integer */ abstract function fileModified($filename); /** * Переименовывает существующий файл в директории. * * @param string $from * @param string $to * @return void */ abstract function renameFile($from, $to); /** * Устанавливает время изменения файла в текущее. * * @param string $filename * @return void */ abstract function touchFile($filename); /** * Возвращает объект Zend_Search_Lucene_Storage_File для данного файла в директории. * * @param string $filename * @return Zend_Search_Lucene_Storage_File */ abstract function getFileObject($filename); } ?>
Метод 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
должны быть
перегружены в вашей реализации:
<?php class MyFile extends Zend_Search_Lucene_Storage_File { /** * Устанавливает индикатор позиции и перемещает указатель файла. * Новая позиция, измеряемая в байтах от начала файла, * получается добавлением смещения к позиции, определяемой аргументом $whence, * который может принимать следующие значения: * SEEK_SET - Устанавливает позицию равной смещению в байтах. * SEEK_CUR - Устанавливает позицию равной текущей позиции плюс смещение. * SEEK_END - Устанавливает позицию равной концу файла плюс смещение. * (Для перемещения позиции относительно конца файла вы должны передать отрицательное значение смещения) * В случае успеха возвращает 0; иначе -1 * * @param integer $offset * @param integer $whence * @return integer */ public function seek($offset, $whence=SEEK_SET) { ... } /** * Считывает $length байт из файла и перемещает указатель файла. * * @param integer $length * @return string */ protected function _fread($length=1) { ... } } ?>