18

「-」文字を含むインデックス付き単語を含む Lucene インデックスで問題が発生しています。

「-」を含む一部の単語では機能しますが、すべてでは機能しません。機能しない理由がわかりません。

私が検索しているフィールドが分​​析され、「-」文字の有無にかかわらず単語のバージョンが含まれています。

私はアナライザーを使用しています: org.apache.lucene.analysis.standard.StandardAnalyzer

ここに例があります:

「gsx-*」を検索すると、結果が得られました。インデックス付きフィールドには「SUZUKI GSX-R 1000 GSX-R1000 GSXR」が含まれています。

しかし、「v-*」を検索しても結果は得られませんでした。期待される結果のインデックス付きフィールドには、「SUZUKI DL 1000 V-STROM DL1000V-STROMVSTROM V STROM」が含まれます。

「*」なしで「v-strom」を検索すると機能しますが、たとえば「v-str」だけを検索すると結果が得られません。(ネットショップのライブ検索用なので結果はあるはず)

では、2 つの期待される結果の違いは何でしょうか? 「gsx- 」では機能するのに「v-」では機能しないのはなぜですか?

4

4 に答える 4

18

StandardAnalyzer はハイフンを空白として扱うと思います。at は 1 文字のトークンも排除するため、クエリ"gsx-*"を無"gsx*"に変換します。"v-*"検索結果のフィールド コンテンツとして表示されるのは、フィールドの格納された値であり、そのフィールドにインデックス付けされた用語とは完全に無関係です。

したがって、「v-strom」全体が索引付きの用語になることが必要です。StandardAnalyzerこの種のテキストには適していません。WhitespaceAnalyzerまたはを試してみてSimpleAnalyzerください。それでもうまくいかない場合は、独自のアナライザーを一緒に投げるか、これらの 2 つのメンションから始めて、さらにTokenFilters. Lucene Analysis パッケージの Javadocには、非常に適切な説明が記載されています。

ところで、V-strom、V-Strom などのように、すべてのバリアントをインデックスに入力する必要はありません。同じアナライザーが、インデックス内とクエリの解析中にこれらすべてのバリアントを同じ文字列に正規化するという考え方です。

于 2012-04-17T07:42:20.947 に答える
4

ClassicAnalyzerは、「-」を便利な非区切り文字として処理します。私が理解しているように、ClassicAnalyzer は 3.1 以前の StandardAnalyzer のように「-」を処理します。これは、ClassicAnalyzer が「-」が埋め込まれた数字を製品コードとして扱うClassicTokenizerを使用するため、すべてが 1 つの用語としてトークン化されるためです。

私が Regenstrief Institute にいたとき、Luke をアップグレードした後にこれに気付きました。LOINC の標準的な医学用語 (LOINC は RI によって開始された) は、「1-8」や「2857」のように、数字の後に「-」とチェックディジットが続くことで識別されるためです。 -1'. 「45963-6」のような LOINC の検索は、Luke 3.5.0 で StandardAnalyzer を使用すると失敗しましたが、ClassicAnalyzer では成功しました (これは、2.9.2 Lucene.NET でインデックスを構築したためです)。

于 2012-04-17T20:48:36.103 に答える
1

「GSX-R1000」などの製品コードを含むテキストの索引付けには、ClassicAnalzer をお勧めします。これを単一の用語として認識し、その部分を分割しませんでした。ただし、たとえば、「Europe/Berlin」というテキストは、ClassicAnalzer によって「Europe」と「Berlin」という単語に分割されます。これは、ClassicAnalyzer によって索引付けされたテキストに次のフレーズが含まれている場合を意味します。

Europe/Berlin GSX-R1000

「ヨーロッパ」、「ベルリン」、または「GSX-R1000」で検索できます。

ただし、検索に使用するアナライザーには注意してください。Lucene インデックスを検索するには、KeywordAnalyzer が最適だと思います。KeywordAnalyzer を使用すると、ドキュメント内の特定のフィールドを検索したり、次のような複雑なクエリを作成したりできます。

(processid:4711) (berlin) 

このクエリは、「berlin」という語句を含むドキュメントを検索しますが、4711 という数字を含む「processid」フィールドも検索します。

しかし、インデックスで「europe/berlin」という語句を検索しても、結果は得られません。これは、KeywordAnalyzer が検索フレーズを変更しなかったためですが、'Europe/Berlin' というフレーズが ClassicAnalyzer によって 2 つの別個の単語に分割されたためです。つまり、「ヨーロッパ」と「ベルリン」を別々に検索する必要があります。

この競合を解決するには、次のコードを使用して、ユーザーが入力した検索語をニーズに合った検索クエリに翻訳します。

QueryParser parser = new QueryParser("content", new ClassicAnalyzer());
Query result = parser.parse(searchTerm);
searchTerm = result.toString("content");

このコードは、serach pharse を変換します

Europe/Berlin

の中へ

europe berlin

これにより、期待されるドキュメント セットが生成されます。

注:これは、より複雑な状況でも機能します。検索語

Europe/Berlin GSX-R1000

に翻訳されます:

(europe berlin) GSX-R1000

KeyWordAnalyzer を使用して、すべてのフレーズを組み合わせて正しく検索します。

于 2016-07-14T06:21:40.600 に答える