2011-11-08 10 views
0

次のプログラム:LuceneのQueryParser一貫性のない行動

\ -> __catch_all:foo __catch_all:bar 
+ -> __catch_all:foo __catch_all:bar 
- -> __catch_all:foo __catch_all:bar 
! -> __catch_all:foo __catch_all:bar 
(-> __catch_all:foo __catch_all:bar 
) -> __catch_all:foo __catch_all:bar 
: -> __catch_all:foo:bar 
^ -> __catch_all:foo __catch_all:bar 
[ -> __catch_all:foo __catch_all:bar 
] -> __catch_all:foo __catch_all:bar 
" -> __catch_all:foo __catch_all:bar 
{ -> __catch_all:foo __catch_all:bar 
} -> __catch_all:foo __catch_all:bar 
~ -> __catch_all:foo __catch_all:bar 
* -> __catch_all:foo __catch_all:bar 
? -> __catch_all:foo __catch_all:bar 
| -> __catch_all:foo __catch_all:bar 
& -> __catch_all:foo __catch_all:bar 

注意して見かけ上の矛盾を::

import java.util.Arrays; 
import java.util.List; 

import org.apache.lucene.analysis.standard.StandardAnalyzer; 
import org.apache.lucene.queryParser.ParseException; 
import org.apache.lucene.queryParser.QueryParser; 
import org.apache.lucene.util.Version; 

public class LuceneTest { 

    static final List<Character> SPECIAL_CHARS = 
     Arrays.asList('\\', '+', '-', '!', '(', ')', ':', '^', '[', ']', '"', '{', '}', '~', '*', '?', '|', '&'); 

    public static void main(String[] args) throws ParseException { 
    QueryParser query = 
     new QueryParser(Version.LUCENE_31, "", new StandardAnalyzer(Version.LUCENE_31)); 


    for (char c : SPECIAL_CHARS) { 
     System.out.println(c + " -> " + query.parse("__catch_all:foo\\" + c + "bar").toString()); 
    } 
    } 

} 

は、この出力を与え、また、私は正確にやって特殊文字を(エスケープてることに注意してくださいQueryParser.escapeと同じです)。私は、StandardAnalyzerがクエリ用語から特別な句読点を取り除くことを期待しています。ほとんどすべてのケースでそうです。

これは特に矛盾すると思われる理由は、StandardAnalyzerとフィールドテキスト "foo:bar"を使って文書を書くとという2つのという用語フィールド、foo、barが得られるからです!

エスケープの2回目は正しい結果、つまり効果的に "foo \\:bar"を返します。しかし、なぜこれはコロンだけに必要ですか?なぜこの動作を避けるためにQueryParser.escape(QueryParser.escape(mystring))を行う必要がありますか?

答えて

0

':'の異なる処理は、QueryParserの障害ではなく、StandardAnalyzerの障害です。実際には、 ':'はStandardAnalyzerによって区切り文字とみなされない唯一の文字です。結果として、「a:b」を分析すると、1つのトークン「a:b」が得られ、一方、「a'b」を分析すると、2つのトークン「a」および「b」が得られる。ここで

は何が起こるかです:偉大な情報は、感謝です

Original String -> unescaped string -> tokens -> query

"foo\:bar" -> "foo:bar" -> [ "foo:bar" ] -> TermQuery(__catch_all, "foo:bar")

"foo\+bar" -> "foo+bar" -> [ "foo", "bar" ] -> TermQuery(__catch_all, "foo") OR TermQuery(__catch_all, "bar")

+0

。 * write *側では、StandardAnalyzerが文字列を "foo bar"としてトークン化しているように見えますが、これは矛盾しているようです。 – HenryR

+0

あなたはどう思いますか?この問題を示すコードを提供できますか? – jpountz

関連する問題