我有一个字段,比如F,我通过使用KeywordTokenizer,Lowercase Filter和TrimFilter进行未分析。
当我触发F的过滤器查询时,过滤器查询被解析为TermQuery而不是PhraseQuery ..
这是我的过滤查询 -
filter=F:"A B C"
以下是我正在尝试的代码 -
String fqs [] = msParams.getParams("fq");//msParams is ModifiableSolrParams
if(fqs != null) {
for(int i=0; i<fqs.length; i++) {
try {
String field = null;
QParser fqp = QParser.getParser(fqs[i], null, req);//req is request
if(fqp.getQuery() instanceof TermQuery) {
TermQuery fq = (TermQuery) fqp.getQuery();
field = fq.getTerm().field();
我的问题是 - 为什么像F:"A B C"
这样的查询被 solr 解析为TermQuery而不是PhraseQuery?
答案 0 :(得分:0)
在探索代码后发现了正在发生的事情 -
如果令牌的数量是1(我有KeywordTokenizer的情况),上面的查询被解析为TermQuery,否则对于多于1个令牌,它会查找布尔查询或短语查询。
源文件 - SolrQueryParserBase.java第461行(Solr - 4.5.0)
if (numTokens == 0)
return null;
else if (numTokens == 1) {
try {
boolean hasNext = buffer.incrementToken();
assert hasNext == true;
termAtt.fillBytesRef();
} catch (IOException e) {
// safe to ignore, because we know the number of tokens
}
return newTermQuery(new Term(field, BytesRef.deepCopyOf(bytes)));
} else {
if (severalTokensAtSamePosition || (!quoted && !autoGeneratePhraseQueries)) {
if (positionCount == 1 || (!quoted && !autoGeneratePhraseQueries)) {
// no phrase query:
BooleanQuery q = newBooleanQuery(positionCount == 1);
BooleanClause.Occur occur = positionCount > 1 && operator == AND_OPERATOR ?
BooleanClause.Occur.MUST : BooleanClause.Occur.SHOULD;
for (int i = 0; i < numTokens; i++) {
try {
boolean hasNext = buffer.incrementToken();
assert hasNext == true;
termAtt.fillBytesRef();
} catch (IOException e) {
// safe to ignore, because we know the number of tokens
}
Query currentQuery = newTermQuery(
new Term(field, BytesRef.deepCopyOf(bytes)));
q.add(currentQuery, occur);
}
return q;
}
else {
// phrase query:
MultiPhraseQuery mpq = newMultiPhraseQuery();
mpq.setSlop(phraseSlop);
List<Term> multiTerms = new ArrayList<Term>();
int position = -1;
for (int i = 0; i < numTokens; i++) {
int positionIncrement = 1;
try {