Zend Lucene和通配符运算符怪异

时间:2010-12-02 06:13:48

标签: php zend-framework lucene wildcard zend-search-lucene

我的问题的快速摘要,通配符运算符似乎没有返回我期望的结果。我正在针对某个Keyword字段对此进行测试。

以下是一个显示问题的示例

include 'Zend/Loader/Autoloader.php';
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setFallbackAutoloader(true);


Zend_Search_Lucene_Analysis_Analyzer::setDefault(
    new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8_CaseInsensitive());
@mkdir('/tmp/test-lucene');
$index = Zend_Search_Lucene::create('/tmp/test-lucene');
$doc = new Zend_Search_Lucene_Document();
$doc->addField(Zend_Search_Lucene_Field::Keyword('path', 'root/1/2/3'));
$doc->addField(Zend_Search_Lucene_Field::UnStored('contents', 'The lazy fox jump over the dog bla bla bla'));
$index->addDocument($doc);


$doc = new Zend_Search_Lucene_Document();
$doc->addField(Zend_Search_Lucene_Field::Keyword('path', 'root/1'));
$doc->addField(Zend_Search_Lucene_Field::UnStored('contents', 'The lazy fox jump over the dog bla bla bla'));
$index->addDocument($doc);

$doc = new Zend_Search_Lucene_Document();
$doc->addField(Zend_Search_Lucene_Field::Keyword('path', 'root/3/2/1'));
$doc->addField(Zend_Search_Lucene_Field::UnStored('contents', 'The lazy fox jump over the dog bla bla bla'));
$index->addDocument($doc);

$doc = new Zend_Search_Lucene_Document();
$doc->addField(Zend_Search_Lucene_Field::Keyword('path', 'root/3/2/2'));
$doc->addField(Zend_Search_Lucene_Field::UnStored('contents', 'The lazy fox jump over the dog bla bla bla'));
$index->addDocument($doc);

$hits = $index->find('path:root/3/2*');
foreach($hits as $hit){
    $doc = $hit->getDocument();
    echo $doc->getFieldValue('path') . PHP_EOL;
}

这将返回整个文档集,而不是像我期望的那样返回最后两个文档

输出:

root/1/2/3
root/1
root/3/2/1
root/3/2/2

所以这里我的问题为什么lucene(在这种情况下是Zend_Lucene)匹配第一个文档,我认为Keyword字段没有被标记化。

PS:对于那些可能想知道我为什么要运行此测试的人。我有一个带有一些数据库的电子商务网站,类别表有一些路径字段。例如,一个类别可能有这个路径'/ 1/2/3',这意味着它的类别为id 3,父类别为索引2等...

问题是当用户进行全文搜索并指定类别时,理想情况下我想从该类别返回结果,但也要返回子类别,所以我需要一种简单的方法来做路径LIKE'/ 1/2% ”。

另一种可能性是合并SQL查询和lucene命中的结果,如果可能的话我想避免这种情况,因为它可能表现不佳。

如果您有任何想法,欢迎您。

1 个答案:

答案 0 :(得分:1)

使用Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num_CaseInsensitive并将斜杠替换为路径中未出现但是Zend_Search_Lucene的单词字符的字符。我用过德语。

include 'Zend/Loader/Autoloader.php';
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setFallbackAutoloader(true);

Zend_Search_Lucene_Analysis_Analyzer::setDefault(
    new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num_CaseInsensitive());
@mkdir('/tmp/test-lucene');
$index = Zend_Search_Lucene::create('/tmp/test-lucene');

foreach (array('root/1/2/3', 'root/1', 'root/3/2/1', 'root/3/2/2') as $path) {
    $path = str_replace('/', 'ß', $path);
    $doc = new Zend_Search_Lucene_Document();
    $doc->addField(Zend_Search_Lucene_Field::Keyword('path', $path));
    $index->addDocument($doc);
}

$hits = $index->find(str_replace('/', 'ß', 'path:root/3/2*'));
foreach($hits as $hit){
    echo str_replace('ß', '/', $hit->getDocument()->getFieldValue('path')) . PHP_EOL;
}