23

これが事です。「-」などの特殊文字を含む用語がインデックスに保存されています。最も単純なコードは次のとおりです。

Document doc = new Document();
doc.add(new TextField("message", "1111-2222-3333", Field.Store.YES, Field.Index.NOT_ANALYZED));
writer.addDocument(doc);

そして、次のように、QueryParser を使用してクエリを作成します。

String queryStr = "1111-2222-3333";
QueryParser parser = new QueryParser(Version.LUCENE_36, "message", new StandardAnalyzer(Version.LUCENE_36));
Query q = parser.parse(queryStr);

そして、サーチャーを使用してクエリを検索しましたが、結果が得られません。私もこれを試しました:

Query q = parser.parse(QueryParser.escape(queryStr));

そしてまだ結果はありません。

QueryParser を使用せずに、代わりに TermQuery を直接使用すると、私が望むことができますが、この方法ではユーザー入力テキストに対して十分な柔軟性がありません。

おそらく、StandardAnalyzer がクエリ文字列の特殊文字を省略するために何かをしたと思います。デバッグを試みたところ、文字列が分割されており、実際のクエリは「メッセージ:1111 メッセージ:2222 メッセージ:3333」のようになっていることがわかりました。ルセンが何をしたのか正確にはわかりません...

では、特殊文字を使用してクエリを実行したい場合は、どうすればよいでしょうか? アナライザーを書き直すか、デフォルトのものからクエリパーサーを継承する必要がありますか? で、どうやって?...

アップデート:

1 @The New Idiot @femtoRgon、問題に記載されているように QueryParser.escape(queryStr) を試しましたが、まだ機能しません。

2 問題を解決する別の方法を試しました。Tokenizer から QueryTokenizer を派生させ、単語をスペースだけで切り取り、Analyzer から派生した QueryAnalyzer にパックし、最後に QueryAnalyzer を QueryParser に渡します。

今では動作します。クエリが QueryParser に渡されると、デフォルトの StandardAnalyzer がデフォルトのルール (一部の特殊文字をスプリッターとして認識する) に従って queryStr をカットするため、本来は機能しません。特殊文字は StandardAnalyzer によって既に削除されています。今、私は独自の方法を使用して queryStr を切り取り、スペースのみをスプリッターとして認識するため、特殊文字は処理を待っているクエリに残り、これは機能します。

3 @The New Idiot @femtoRgon、私の質問に答えてくれてありがとう。

4

2 に答える 2

23

-これについてはよくわかりませんが、 でエスケープする必要があると思います\Lucene docsに従って。

「-」または禁止演算子は、「-」記号の後に用語を含むドキュメントを除外します。

また 、

Lucene は、クエリ構文の一部である特殊文字のエスケープをサポートしています。現在のリストの特殊文字は

+ - && || ! ( ) { } [ ] ^ " ~ * ? : \ /

これらの文字をエスケープするには、文字の前に \ を使用します。

また、Java で特別な意味を持つ場合、2 回エスケープする必要がある文字もあることを覚えておいてください。

于 2013-07-24T15:59:55.127 に答える
0

add または addText の代わりに addValue() として値を追加できます。次に、Standard Analyzer の代わりに KyewordAnalyzer を使用して特殊文字を検索します。または addValue() を使用してデータを追加し、luke でデータを検索するときに、特殊文字をワイルド カード検索文字 (?) に置き換えます。私は両方の方法と作品を試しました

于 2016-07-25T18:14:39.410 に答える