Производить поиск по индексу можно двумя способами. Первый способ использует парсер запросов для построения запросов из строки. Второй способ дает возможность создавать свои запросы через программный интерфейс Zend_Search_Lucene.
Перед тем, как выбрать использование парсера запросов, пожалуйста, учтите следующее:
Если вы программно генерируете строку запроса и затем парсите ее с помощью парсера запросов, то вам следует серьезно подумать о построении запросов непосредственно через программный интерфейс. Другими словами, парсер запросов предназначен для текста, вводимого пользователем, а не генерируемого программным способом.
Не разбитые на лексемы поля лучше добавлять непосредственно в запросы, а не через парсер запросов. Если значения полей программно генерируются приложением, то должны быть отдельные элементы запроса для этого поля. Анализатор, используемый парсером запросов, предназначен для преобразования введенного пользователем текста в элементы запроса. Программно генерируемые значения, такие, как даты, ключевые слова и т.д., должны генерироваться единообразно.
В форме запроса поля с основным текстом должны использовать парсер запросов. Все остальные, такие, как периоды времени, ключевые слова и т.д, лучше добавлять непосредственно через программный интерфейс для запросов. Поля с ограниченным набором значений, которые могут отображаться в виде выпадающего списка, лучше не добавлять в строку запроса, которая парсится, а как элемент запроса.
Булевы запросы позволяют объединять несколько запросов в один. Таким образом, это является наилучшим путем добавления дополнительных критериев пользовательского поиска, определяемых строкой запроса.
Оба способа используют один и тот же метод программного интерфейса для поиска в индексе:
<?php require_once('Zend/Search/Lucene.php'); $index = new Zend_Search_Lucene('/data/my_index'); $index->find($query); ?>
Метод Zend_Search_Lucene::find()
автоматически определяет
тип ввода и использует парсер запросов для построения соответствующего
объекта Zend_Search_Lucene_Search_Query.
Важно отметить, что парсер запросов использует стандартный анализатор для разбиения на лексемы отдельных частей строки запроса. Таким образом, все преобразования, проделываемые с индексируемым текстом, также проделываются и с частями строки запроса.
Это могут быть приведение к нижнему регистру для того, чтобы сделать поиск нечувствительным к регистру, удаление запрещенных слов и т.д.
В противоположность парсеру запросов, методы API не преобразовывают или фильтруют входные элементы. Таким образом, API является более подходящим для сгенерированных компьютером или не разбитых на лексемы полей.
Результаты поиска по умолчанию сортируются по рангу. Вы можете изменить это поведение посредством установки поля (полей) для сортировки, типа сортировки и порядка соритровки.
Метод $index->find()
может принимать несколько
необязательных параметров:
$index->find($query [, $sortField [, $sortType [, $sortOrder]]] [, $sortField2 [, $sortType [, $sortOrder]]] ...);
$sortField
- имя сохраненного в индексе поля
для сортировки результатов.
$sortType
может быть пропущено или принимать значения
SORT_REGULAR
(сравнивает элементы списка как обычно,
значение по умолчанию), SORT_NUMERIC
(сравнивает
элементы списка как числа), SORT_STRING
(сравнивает
элементы списка как строки).
$sortOrder
может быть пропущен или принимать значения
SORT_ASC
(сортировка в возрастающем порядке, значение
по умолчанию), SORT_DESC
(сортировка в убывающем
порядке).
Примеры:
$index->find($query, 'quantity', SORT_NUMERIC, SORT_DESC);
$index->find($query, 'fname', SORT_STRING, 'lname', SORT_STRING);
$index->find($query, 'name', SORT_STRING, 'quantity', SORT_NUMERIC, SORT_DESC);
Пожалуйста, будьте внимательны, когда используете порядок сортировки, отличный от принятого по умолчанию. Для него нужно полное извлечение документов из индекса, что может значительно снизить скорость поиска.
Результаты поиска являются массивом объектов Zend_Search_Lucene_Search_QueryHit.
Каждый из них имеет два свойства: $hit->document
является номером документа в индексе, и $hit->score
,
который является рангом результата поиска. Результаты
упорядочены по рангу (результаты с наивысшим рангом идут первыми).
Объект Zend_Search_Lucene_Search_QueryHit также предоставляет все поля Zend_Search_Lucene_Document, представляюшего собой найденный документ. Например, соответствующий документ имеет два поля: title (название) и author (автор).
<?php require_once('Zend/Search/Lucene.php'); $index = new Zend_Search_Lucene('/data/my_index'); $hits = $index->find($query); foreach ($hits as $hit) { echo $hit->id; echo $hit->score; echo $hit->title; echo $hit->author; } ?>
При необходимости исходный объект Zend_Search_Lucene_Document (документ) может быть получен из Zend_Search_Lucene_Search_QueryHit. Вы можете извлечь сохраненные в индексе части документа, используя метод getDocument() объекта индекса, и затем получить их через метод getFieldValue().
<?php require_once('Zend/Search/Lucene.php'); $index = new Zend_Search_Lucene('/data/my_index'); $hits = $index->find($query); foreach ($hits as $hit) { // возвращает объект для этого "хита" echo $document = $hit->getDocument(); // возвращает объект Zend_Search_Lucene_Field // из Zend_Search_Lucene_Document echo $document->getField('title'); // возвращает строковое значение объекта Zend_Search_Lucene_Field echo $document->getFieldValue('title'); // делает то же самое, что и getFieldValue() echo $document->title; } ?>
Поля, доступные через объект Zend_Search_Lucene_Document, определяются во время индексирования. Поля документа либо только индексируются, либо индексируются и сохраняются в индексе индесирующим приложением (например, LuceneIndexCreation.jar).
Обратите внимание, что идентификатор документа (в нашем примере — 'path') также сохраняется в индексе и должен извлекаться из него.
Zend_Search_Lucene использует тот же самый алгоритм ранжирования, что и Java Lucene. Результаты поиска упорядочиваются по рангу (релевантности). "Хиты" с наибольшим рангом идут первыми.
Различные ранги результатов означают, что один документ больше соответствует запросу, чем другой.
Приблизительно говоря, документы, в которых искомый элемент или фраза встречаются чаще, будут иметь более высокий ранг.
Число, соответствующее рангу, может быть получено через
свойство score
:
<?php $hits = $index->find($query); foreach ($hits as $hit) { echo $hit->id; echo $hit->score; } ?>
Для вычисления ранга используется класс Zend_Search_Lucene_Search_Similarity. За подробностями см. раздел Расширяемость. Алгоритмы ранжирования.