2012-12-24 225 views
1

当我搜索特殊字符如“#”时,没有结果出现。用Zend搜索索引和搜索特殊字符Lucene

请注意,我已经转义了查询字符串。

但是,当与诸如“c#”之类的字母组合时,Lucene会找到该术语。

有什么办法可以搜索单个特殊字符吗?

这里是我的片断:

Zend_Search_Lucene_Search_Query_Wildcard::setMinPrefixLength(1);

Zend_Search_Lucene_Analysis_Analyzer::setDefault(
    new \Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num_CaseInsensitive());    

$index = Zend_Search_Lucene::create('/tmp/index');  
$doc = new Zend_Search_Lucene_Document; 
$doc->addField(Zend_Search_Lucene_Field::Text('title', 'Some Title Here', 'UTF-8')) 
    ->addField(Zend_Search_Lucene_Field::Text('content-01', '+ @ #', 'UTF-8')) 
    ->addField(Zend_Search_Lucene_Field::Text('content-02', 'C+ C#', 'UTF-8'));   

$index->addDocument($doc); 
$index->commit(); 

/* returns 0 results */ 
$r = $index->find("/#"); 
echo count($r) . "\n"; 

/* returns 1 results */ 
$r = $index->find('C#'); 
echo count($r) . "\n"; 

/* returns 1 results */ 
$r = $index->find('C+'); 
echo count($r) . "\n"; 

+0

'$ index->​​ find('C');'返回任何结果 –

+0

非常正确。我希望有人能提供一个解决方案或至少一个解释。 – EngineerCoders

+0

@NandakumarV和工程师 - 工作一小时后我有一些解决方案 - 检查我的答案 – Karol

回答

4

根据这一page特殊字符名单如下:

所以,你不应该逃避#。但即使你不使用转义'斜线',你仍然会得到0的结果。即使将Text字段类型更改为Keyword,也无法解决此问题。

于是我开始研究它,并运行这段代码:

echo('<pre>'); 
var_dump(Zend_Search_Lucene_Search_QueryParser::parse("#")); 
echo('</pre>'); 
die(); 

它返回Zend_Search_Lucene_Search_Query_Boolean对象与Zend_Search_Lucene_Search_Query_Preprocessing_Term类型的一个子查询。什么是有趣的,根据documentation

这是旨在查询解析后最终确定ASE查询 处理的内部抽象类。

这种查询类型不是实际上涉及查询执行

所以我唯一的想法是:不要使用默认PARSER ANYMORE!

所以,我认为你的问题的解决方案很简单 - 建立查询使用query construction API手动:

$term = new Zend_Search_Lucene_Index_Term("#"); 
$query = new Zend_Search_Lucene_Search_Query_Term($term); 

/* still returns 0 results!! */ 
$r = $index->find($query); 
echo('<pre>'); 
var_dump(count($r)); 
echo('</pre>'); 

,但它不工作了!

我做了它的工作(与查询分析器以及)的唯一途径是通过加入这一行:

->addField(Zend_Search_Lucene_Field::keyword('content-03', '#')) 

因此,假设:特殊字符只能被搜索的关键字,因为这些字段是不记号化。但关键词被视为一个完整的短语(即使有短语),这是一个巨大的局限性。