Zend Lucene で「Foo Bar」を検索するときに「FooBar」を見つける方法
-
03-07-2019 - |
質問
Zend Lucene を使用して PHP Web サイトの検索機能を構築していますが、問題が発生しています。私のWebサイトはショップディレクター(のようなもの)です。
たとえば、「FooBar」という名前のショップがありますが、訪問者は「Foo Bar」を検索しても結果はゼロです。また、店の名前が「Foo Bar」で、訪問者が「FooBar」を検索しても何も見つかりません。
「 foobar~ 」(あいまい検索)で検索してみましたが、「Foo Bar」という名前の記事は見つかりませんでした。
インデックスを構築したりクエリを作成したりする特別な方法はありますか?
解決
オプション1:入力クエリ文字列をさまざまな場所で 2 つの部分に分割し、検索します。例えば。この場合、クエリは (+fo +bar) OR (+foo +bar) OR (+foob +ar) になります。問題は、このトークン化では入力クエリ文字列に 2 つのトークンがあると想定していることです。また、(+foob +ar) の結果など、おそらく無関係な追加の結果が得られる場合があります。
オプション 2:インデックス作成とクエリ時に N-gram トークン化を使用します。「foo bar」のトークンにインデックスを付ける場合は、fo、oo、ba、ar になります。foobar で検索すると、トークンは fo、oo、ob、ba、ar になります。演算子として OR を使用して検索すると、n グラム一致が最大のドキュメントが上部に表示されます。これは次の方法で実現できます NGramTokenizer
他のヒント
最も一般的な名前の混乱に対しては、インデックス エントリを手動で追加します。顧客に特別なフォームに入力してもらいます。
「*foo* AND *bar*」または「*foo* OR *bar*」は試しましたか?Ferret で動作し、Lucene に基づいていると読みました。
パフォーマンスを気にしない場合は、WildcardQuery を使用してください (パフォーマンスは大幅に低下します)。
new WildcardQuery( new Term( "propertyName", "Foo?Bar" ) );
0 個以上の文字の場合は「*」を使用し、0 個または 1 個の文字の場合は「?」を使用します。
パフォーマンスが重要な場合は、BooleanQuery を使用してみてください。