Lucene TermQuery vs PhraseQuery:此过滤查询包含术语查询或短语查询?

时间:2014-09-25 05:35:18

标签: solr lucene

我有一个字段,比如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?

1 个答案:

答案 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 {