2013-07-24 1 views
17

ここに事があります。QueryParserを使用して特殊文字を含むluceneクエリを実行するには?

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がクエリ文字列内の特殊文字を省略する何かをしたと思います。私はデバッグを試みました。文字列が分割され、実際のクエリは次のようになっています。 "message:1111 message:2222 message:3333"私は正確にルーネンが何をしたのか分かりません...

私は特殊文字で質問を実行したいのですが、どうすればいいですか?アナライザーを書き直すか、クエスターをデフォルトのものから継承するべきですか?そして、どのように...

更新:?問題で述べたが、それはまだ動作しないよう

1 @The新白痴@femtoRgon、私が試したQueryParser.escape(queryStr)。

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

これで機能します。元のStandardAnalyzerは、QueryParserに渡されたときに特殊文字がすでにStandardAnalyzerによって削除されている場合、デフォルトのStandardAnalyzerがデフォルトのルール(スプリッタとして一部の特殊文字を認識する)に従ってqueryStrを切り捨てるため、元々は機能しません。今私は独自の方法でqueryStrを切り取り、スプリッタとしてのスペースしか認識しないので、特殊文字は処理待ちのクエリに残っています。

3 @ New Idiot @femtoRgon、私の質問にお答えいただきありがとうございます。

+1

私は明らかに十分に慎重に読んでいませんでした。私は混乱しています:この 'TextField'はどこから来ていますか? Luceneの 'TextField'は' Field.Index'引数をとりません( 'Field.Index'は廃止予定です)。ここにあるようなフィールドを作成するには、代わりに 'StringField'を使用します。これはカスタムの 'TextField'なのでしょうか? – femtoRgon

+0

申し訳ありませんが、それは私のせいです。私はLucene 3.6を使用しており、Lucene 3.xにはTextFieldはありません。正しいコードは 'doc.add(新しいフィールド(" message "、" 1111-2222-3333 "、Field.Store.YES、Field.Index.NOT_ANALYZED));' Lucene 4.xと3.xのAPI私はまだlucene 4.xのAPIを理解しようとしています。 –

+0

ああ、より理にかなっています。トピックを少しは削除しましたが、4.xの変更を処理しようとしている場合は、[移行ガイド](http://lucene.apache.org/core/4_0_0/MIGRATE.html)を参照してください。それは大きな変更を呼び出すとともに、いくつかの根拠を提供します。 – femtoRgon

答えて

19

私はこのことについてはわかりませんが、-\に逃がす必要があると思います。 Lucene docsに従ってください。

「 - 」または禁止オペレータは、「 - 」記号の後にその語句を含む文書を除外します。再び

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

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

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

Javaで特別な意味がある場合は、2回エスケープする必要がある文字もあります。

+0

答えをくれてありがとう、私はこれを解決する方法を見つけました、plsは私の更新を見ます。 –

+1

Lucene 4.0から始まる "/"も特殊文字(regexで使用される)であることを忘れないでください。 –

0

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