現在、私が取り組んでいるプロジェクトの検索エンジンとして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"
) を検索すると、正しいドキュメントが返されます。
フィールド内での検索を防ぐために何が問題になっていますか?