2012-05-03 26 views
1

私は現在、私が取り組んでいるプロジェクトの検索エンジンとしてのZend_Search_Luceneを設定しています。Zend Search 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ワード。計画は、各単語のsoundexと他のフィールドのフィールドを検索することです。したがって、誰かが '肉肉'と 'maet'をミスペルドした場合、 'M300'と同じになるため、結果は返されます。

私はLukeを使用してデータセットを表示し、正しい条件を見ています。 Lukeを使用してsoundex(すなわちsoundex:M300)を検索すると、結果は返されませんが、フィールド全体(つまり、soundex:"J500 M534 M300 B200")を検索すると正しい文書が返されます。

フィールド内での検索を防ぐにはどうしたらいいですか?

答えて

0

私がZend_Search_Lucene_Field :: keywordを正しく理解していれば(上記の "soundex"で使用したもの)、一度に1つの値(単一の日付または単一のURLなど)を格納するように設計されています。

"soundex"フィールドでは、代わりにZend_Search_Lucene_Field :: textのようなトークン化ストレージメソッドを使用したいと思います。これは、フィールド全体だけでなく、 "soundex"フィールドの個々のトークンを検索するように思えます値。

+0

こんにちはマーク、情報ありがとうございます。私はもともとテキストフィールドとしてそれを持っていたが、それを変更した。この変更の理由は、ルークがsoundexフィールドのトップランクの用語を1文字(b、s、rなど)で表示したためです。したがって、私がsoundex:mを検索すると、soundex MXXXがあるところですべての結果が表示されます。奇妙なことに私を当てるのは、その言葉に数字がないということです。トークン化されたフィールドの数値は無視されますか? –

+0

それを並べ替え、デフォルトのアナライザーを変更しなければならなかったのは、数字を用語の一部として扱わないことを学んだからです。インデックスを作成する前とインデックスを検索する前に、 'Zend_Search_Lucene_Analysis_Analyzer :: setDefault(new Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum_CaseInsensitive()); 'を追加しました。 –

関連する問題