2012-05-03 195 views
1

我目前有Zend_Search_Lucene设置为我正在处理的项目上的搜索引擎。Zend搜索Lucene - 搜索特定字段

它在默认级别工作很好(即搜索所有字段),但是我现在需要搜索特定字段。

原因是因为我试图编码处理拼写错误的能力。因此,我在文档标题中添加每个单词的soundex。

例如:

$productArray['title'] = 'June Monthly Meat Box'; 
$doc = new Zend_Search_Lucene_Document(); 
$doc->addField(Zend_Search_Lucene_Field::text('product_title', $productArray['title'])); 
$soundex = implode(' ', array_map('soundex', array_map('trim', preg_split('/ /', $productArray['title'], NULL, PREG_SPLIT_NO_EMPTY)))); 
$doc->addField(Zend_Search_Lucene_Field::keyword('soundex', $soundex)); 
$index->addDocument($doc); 

这增加了 'J500 M534 M300 B200' 为同音字段。

这是如何进行搜索:

$queryString = trim(urldecode($this->_request->getParam('q'))); 
$words = array_map('trim', preg_split('/ /', $queryString, NULL, PREG_SPLIT_NO_EMPTY));  

$query = new Zend_Search_Lucene_Search_Query_Boolean(); 
$subquery1 = new Zend_Search_Lucene_Search_Query_MultiTerm(); 
foreach($words as $word) 
{ 
    $subquery1->addTerm(new Zend_Search_Lucene_Index_Term($word)); 
} 

$subquery2 = new Zend_Search_Lucene_Search_Query_MultiTerm(); 
foreach($words as $word) 
{ 
     $subquery2->addTerm(new Zend_Search_Lucene_Index_Term(strtolower(soundex($word)), 'soundex')); 
} 
$query->addSubquery($subquery1); 
$query->addSubquery($subquery2); 

变量$subquery1每个原始查询的话(这适用于它自己)
变量$subquery2存储每个的同音店字。计划是在字段中搜索soundex以及每个单词的其他字段。因此,如果有人拼写错误''与'maet',它将返回结果,因为soundex在'M300'处将是相同的。

我使用Luke来查看数据集并看到正确的术语。当我使用Luke搜索soundex(即soundex:M300)时,它不返回任何结果,但是如果我搜索整个字段(即soundex:"J500 M534 M300 B200"),它将返回正确的文档。

什么是错误,以防止它在现场搜索?

回答

0

如果我正确理解了Zend_Search_Lucene_Field :: keyword(您用于上面的“soundex”),它被设计为一次存储单个值(如单个日期或单个URL)。

我想你想,而不是使用像::若干Zend_Search_Lucene_Field文字符号化存储方法的“同音”领域,因为它听起来像你想在“同音”场个人标记搜索,不只是整场值。

+0

嗨马克,感谢您的信息。我原本把它作为一个文本字段,但改变了它。更改原因是因为Luke将soundex字段的排名最高的字词显示为一个字母(如:b,s,r等)。因此,如果我搜索soundex:m确实会在带有soundex MXXX的情况下显示所有结果。令我感到奇怪的是,条款中没有数字。数字字段忽略数字吗? –

+0

排序它,我不得不更改默认分析器,因为我已经知道它不会将数字视为术语的一部分。我添加了'Zend_Search_Lucene_Analysis_Analyzer :: setDefault(new Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum_CaseInsensitive());'在索引创建之前和搜索索引之前。 –