Zend lucene - поиск в текстовых файлах

В настоящее время я работаю над личным проектом, где я читаю отсканированные документы с использованием tesseract и сохраняю содержимое в виде текстовых файлов. Я храню как текстовые файлы, так и файлы jpeg в своем веб-каталоге и поддерживаю связь между ними с помощью базы данных mySQL. Цель проекта — иметь возможность искать ключевые термины и иметь возможность возвращать изображения.

До сих пор мне удавалось индексировать текстовые файлы с помощью Zend Lucene, однако я столкнулся с множеством проблем при поиске документов, поля в моем индексе: дата загрузки изображения, тело (содержимое текстового файла ) и URI изображения.

//Create document
$doc = new Zend_Search_Lucene_Document();

//Select database and get item to be indexed
mysql_select_db("database", $con);

$exampleSQL = "SELECT date_format(dateUploaded, '%Y%m%d') as formatted_date, imageLink, textLink
FROM `mappingTable`
WHERE imageLink='$item'";

$fileItem = mysql_fetch_assoc(mysql_query($exampleSQL));

//Add fields to document
$doc->addField(Zend_Search_Lucene_Field::UnIndexed('URL',
$fileItem['imageLink']));

$doc->addField(Zend_Search_Lucene_Field::Keyword('created',
$fileItem['formatted_date']));

$contents = file_get_contents("/path/to/data/".$fileItem['textLink']);

$doc->addField(Zend_Search_Lucene_Field::UnStored('body',
$contents));

Все вышеперечисленное, я считаю, работает просто отлично. Для своих поисков я намерен искать по содержимому в текстовых файлах и по дате загрузки изображения в каталог, поэтому я разработал следующие запросы, которые по какой-то причине продолжают не выполняться должным образом, особенно при поиске по дате или по содержанию и дате.

if($queryType === "contentSearch"){

    $term  = new Zend_Search_Lucene_Index_Term($query, 'body');

    $searchQuery = new Zend_Search_Lucene_Search_Query_Term($term);

    try{
        $hits = $index->find($searchQuery);
    }
        catch (Zend_Search_Lucene_Exception $ex) {
        $hits = array();
    }

} elseif ($queryType === "dateSearch"){

    $searchQuery = '['.str_replace('/','',$fQuerydate)." TO ".str_replace('/','',$tQuerydate).']';

    try{
        $hits = $index->find($searchQuery);
    }
        catch (Zend_Search_Lucene_Exception $ex) {
        $hits = array();
    }

}  elseif ($queryType === "bothSearch"){

    $searchQuery = new Zend_Search_Lucene_Search_Query_MultiTerm();

    $searchQuery->addTerm(new Zend_Search_Lucene_Index_Term($query, 'body'), true);
    $searchQuery->addTerm(new Zend_Search_Lucene_Index_Term('['.str_replace('/','',$fQuerydate).' TO '.str_replace('/','',$tQuerydate).']', 'created'), true);

    // $searchQuery = 'body:"'.$query.'" && created:'.$fQuerydate." TO ".$tQuerydate;

try{
        $hits = $index->find($searchQuery);
    } catch (Zend_Search_Lucene_Exception $ex) {
        $hits = array();
    }
} else {
    $searchQuery = null;
}

Как вы можете видеть, я даже пытался использовать синтаксический анализатор, но приведенное выше не дало никакого результата, хотя я выполняю поиск, зная, что должны быть возвращены как минимум два документа.

например: +body:hill +created:[20110328 TO 20110628]

Возвращает ноль документов.

Как видите, я избавился от всех '/', '.' и «-» в моем поле даты (создания), и я использовал для него объявление ключевого слова, чтобы убедиться, что оно будет соответствовать поиску, но даже тогда ничего не возвращается.

Я также хотел бы знать, как применить мой собственный стоп-лист для использования, так как есть некоторые термины, которые я хотел бы включить в поиск, которых в настоящее время нет, но они важны для документов.

Поскольку я не работаю на своем собственном сервере и имею к нему ограниченный доступ, у меня нет другого выбора, кроме как использовать lucene или mySQL, не лучше ли мне использовать полнотекстовый поиск в моей БД?

Заранее спасибо.


person Oscar    schedule 28.06.2011    source источник


Ответы (1)


Теперь мне удалось найти способ эффективного поиска по обоим терминам. Это было очень просто, хотя и неявно. Код ниже.

if($queryType === "contentSearch"){

    $term  = new Zend_Search_Lucene_Index_Term($query, 'body');

    $searchQuery = new Zend_Search_Lucene_Search_Query_Term($term);

    try{
        $hits = $index->find($searchQuery);
    }
    catch (Zend_Search_Lucene_Exception $ex) {
        $hits = array();
    }

} elseif ($queryType === "dateSearch"){



    $from = new Zend_Search_Lucene_Index_Term(str_replace('/','',$fQuerydate), 'created');

    $to   = new Zend_Search_Lucene_Index_Term(str_replace('/','',$tQuerydate), 'created');

    $searchQuery = new Zend_Search_Lucene_Search_Query_Range(
                    $from, $to, true // inclusive
                    );

    try{
        $hits = $index->find($searchQuery);
    }
    catch (Zend_Search_Lucene_Exception $ex) {
        $hits = array();
    }

}  elseif ($queryType === "bothSearch"){

    $searchQuery = new Zend_Search_Lucene_Search_Query_Boolean();

    $term  = new Zend_Search_Lucene_Index_Term($query, 'body');

    $subquery1 = new Zend_Search_Lucene_Search_Query_Term($term);

    $from = new Zend_Search_Lucene_Index_Term(str_replace('/','',$fQuerydate), 'created');

    $to   = new Zend_Search_Lucene_Index_Term(str_replace('/','',$tQuerydate), 'created');

    $subquery2 = new Zend_Search_Lucene_Search_Query_Range(
                    $from, $to, true // inclusive
                    );

    $searchQuery->addSubquery($subquery1, true  /* required */);
    $searchQuery->addSubquery($subquery2, true  /* optional */);

    try{
        $hits = $index->find($searchQuery);
    }
        catch (Zend_Search_Lucene_Exception $ex) {
        $hits = array();
    }
}

В результате получается следующий запрос: «+(body:hill) +(created:[20110628 TO 20110629])», который работает.

Теперь мне нужна помощь с реализацией моего собственного стоп-листа, то есть с изменением стоп-листа, используемого lucene.

Ваше здоровье

person Oscar    schedule 29.06.2011