Производить поиск по индексу можно двумя способами. Первый способ использует парсер запросов для построения запросов из строки. Второй способ дает возможность создавать свои запросы через программный интерфейс Zend_Search_Lucene.
В случае выбора парсера запросов учтите следующее:
Если вы программно генерируете строку запроса и затем парсите ее с помощью парсера запросов, то вам следует серьезно подумать о построении запросов непосредственно через программный интерфейс. Другими словами, парсер запросов предназначен для текста, вводимого пользователем, а не генерируемого программным способом.
Не разбитые на лексемы поля лучше добавлять непосредственно в запросы, а не через парсер запросов. Если значения полей программно генерируются приложением, то должны быть отдельные элементы запроса для этого поля. Анализатор, используемый парсером запросов, предназначен для преобразования введенного пользователем текста в элементы запроса. Программно генерируемые значения, такие, как даты, ключевые слова и т.д., должны генерироваться единообразно.
В форме запроса поля с основным текстом должны использовать парсер запросов. Все остальные, такие, как периоды времени, ключевые слова и т.д, лучше добавлять непосредственно через программный интерфейс для запросов. Поля с ограниченным набором значений, которые могут отображаться в виде выпадающего списка, лучше не добавлять в строку запроса, которая парсится, а как элемент запроса.
Булевы запросы позволяют объединять несколько запросов в один. Таким образом, это является наилучшим путем добавления дополнительных критериев пользовательского поиска, определяемых строкой запроса.
Оба способа используют один и тот же метод программного интерфейса для поиска в индексе:
<?php require_once('Zend/Search/Lucene.php'); $index = Zend_Search_Lucene::open('/data/my_index'); $index->find($query);
Метод Zend_Search_Lucene::find()
автоматически определяет
тип ввода и использует парсер запросов для построения соответствующего
объекта Zend_Search_Lucene_Search_Query.
Важно отметить, что парсер запросов использует стандартный анализатор для разбиения на лексемы отдельных частей строки запроса. Таким образом, все преобразования, проделываемые с индексируемым текстом, также проделываются и с частями строки запроса.
Это могут быть приведение к нижнему регистру для того, чтобы сделать поиск нечувствительным к регистру, удаление запрещенных слов и т.д.
В противоположность парсеру запросов, методы API не преобразовывают или фильтруют входные элементы. Таким образом, API является более подходящим для сгенерированных компьютером или не разбитых на лексемы полей.
Метод Zend_Search_Lucene_Search_QueryParser::parse()
может использоваться для парсинга строки запроса и
преобразования ее в объект запроса.
Этот объект может использоваться в методах программного интерфейса для объединения программно сгенерированных запросов с введенными пользователем.
Сейчас в некоторых случаях только таким способом можно будет производить поиск значений в полях, которые не были разбиты на лексемы.
<?php $userQuery = Zend_Search_Lucene_Search_QueryParser::parse($queryStr); $pathTerm = new Zend_Search_Lucene_Index_Term('/data/doc_dir/' . $filename, 'path'); $pathQuery = new Zend_Search_Query_Term($pathTerm); $query = new Zend_Search_Query_Boolean(); $query->addSubquery($userQuery, true /* required */); $query->addSubquery($pathQuery, true /* required */); $hits = $index->find($query);
Метод Zend_Search_Lucene_Search_QueryParser::parse()
также принимает необязательный параметр, через который
указывается кодировка строки запроса.
<?php $userQuery = Zend_Search_Lucene_Search_QueryParser::parse($queryStr, 'iso-8859-5');
Если этот параметр опущен, то используется текущая локаль.
Можно также указать используемую по умолчанию кодировку для
строки запроса через метод Zend_Search_Lucene_Search_QueryParser::setDefaultEncoding()
:
<?php Zend_Search_Lucene_Search_QueryParser::setDefaultEncoding('iso-8859-5'); ... $userQuery = Zend_Search_Lucene_Search_QueryParser::parse($queryStr);
Zend_Search_Lucene_Search_QueryParser::getDefaultEncoding()
возвращает используемую по умолчанию кодировку для строки
запроса (пустая строка означает "текущая локаль").
Результат поиска является массивом объектов
Zend_Search_Lucene_Search_QueryHit. Все эти объекты имеют два
свойства: $hit->document
- номер документа в индексе,
$hit->score
- ранг "хита" в результате поиска.
Результат упорядочен по рангу ("хиты" с наибольшим рангом идут
первыми).
Объект Zend_Search_Lucene_Search_QueryHit также предоставляют все поля документа Zend_Search_Lucene_Document как свойства объекта. В данном примере возвращается "хит" и соответствующий ему документ имеет два поля: заголовок и автор.
<?php require_once('Zend/Search/Lucene.php'); $index = Zend_Search_Lucene::open('/data/my_index'); $hits = $index->find($query); foreach ($hits as $hit) { echo $hit->score; echo $hit->title; echo $hit->author; } ?>
Сохраненные в индексе поля всегда возвращаются в кодировке UTF-8.
Исходный объект документа Zend_Search_Lucene_Document может также
быть получен из Zend_Search_Lucene_Search_QueryHit. Вы можете
извлечь сохраненные в индексе части документа, используя метод
getDocument()
объекта индекса и затем получая из через
метод getFieldValue()
:
<?php require_once('Zend/Search/Lucene.php'); $index = Zend_Search_Lucene::open('/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. За подробностями см. раздел Расширяемость. Алгоритмы ранжирования.
По умолчанию результаты поиска сортируются по рангу. Вы можете изменить это поведение установкой поля (полей) для сортировки, типа сортировки и порядка сортировки.
$index->find()
может принимать несколько необязательных
параметров:
<?php $index->find($query [, $sortField [, $sortType [, $sortOrder]]] [, $sortField2 [, $sortType [, $sortOrder]]] ...);
$sortField
является именем сохраненного в индексе поля
для сортировки результата.
$sortType
может быть опущен или принимать значения
SORT_REGULAR
(сравнивать элементы как обычно, значение по умолчанию),
SORT_NUMERIC
(сравнивать элементы как числа),
SORT_STRING
(сравнивать элементы как строки).
$sortOrder
может быть опущен или принимать значения
SORT_ASC
(сортировать в порядке возрастания, значение по умолчанию),
SORT_DESC
(сортировать в порядке убывания).
<?php $index->find($query, 'quantity', SORT_NUMERIC, SORT_DESC);
<?php $index->find($query, 'fname', SORT_STRING, 'lname', SORT_STRING);
<?php $index->find($query, 'name', SORT_STRING, 'quantity', SORT_NUMERIC, SORT_DESC);
Будьте осторожны, когда используете сортировку, отличную от принятой по умолчанию. Для этого нужно полное извлечение документов из индекса, что может привести к резкому снижению производительности.
Метод
Zend_Search_Lucene_Search_Query::highlightMatches()
позволяет подсвечивать в HTML-документе элементы, присутствующие в
контексте поискового запроса:
<?php $query = Zend_Search_Lucene_Search_QueryParser::parse($queryStr); $hits = $index->find($query); ... $highlightedHTML = $query->highlightMatches($sourceHTML);
Метод highlightMatches()
для обработки HTML использует
класс Zend_Search_Lucene_Document_Html
(см.
раздел
"HTML-документы"). Поэтому этот метод предъявляет те же
требования к HTML-коду, что и используемый класс.