1

現在、私が取り組んでいるプロジェクトの検索エンジンとしてZend_Search_Luceneをセットアップしています。

デフォルト レベル (つまり、すべてのフィールドを検索) ではうまく機能していますが、特定のフィールドを検索する必要があります。

その理由は、スペルミスを処理できるようにコーディングしようとしているからです。そのため、ドキュメントのタイトルに含まれる各単語のサウンドデックスを追加しています。

例えば:

$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);

これにより、soundex フィールドとして「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 」の綴りを間違えた場合、soundex が「 M300 」と同じであるため、結果が返されます。

Lukeを使用してデータセットを表示しており、正しい用語が表示されています。Luke を使用して soundex (つまりsoundex:M300) を検索すると、結果は返されませんが、フィールド全体 (つまりsoundex:"J500 M534 M300 B200") を検索すると、正しいドキュメントが返されます。

フィールド内での検索を防ぐために何が問題になっていますか?

4

1 に答える 1

0

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

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

于 2012-05-08T12:44:13.743 に答える