Solr源码解析之二 -- 支持Lucene查询语法变体

x33g5p2x  于2021-12-20 转载在 其他  
字(2.0k)|赞(0)|评价(0)|浏览(424)
  • 概述
  • 源码分析

概述

Solr除了支持通过各种查询参数查询索引外,还支持通过Lucene查询语法的变体进行查询。
例如:
{!lucene q.op=AND df=text sort=’price asc’}myfield:foo +bar -baz
该查询语句中的”foo +bar -baz”部分需要进行词法分析和语法分析。
Solr采取了与Lucene相同的词法/语法解析方法:即通过JavaCC自动生成词法/语法解析代码。关于JavaCC的知识可以参考以下两篇文章:JavaCC–Linux安装与使用和JavaCC – 生成C++代码。

源码分析

(1)注册LuceneQParserPlugin

public abstract class QParserPlugin implements NamedListInitializedPlugin, SolrInfoMBean {
  /** internal use - name of the default parser */
  public static final String DEFAULT_QTYPE = LuceneQParserPlugin.NAME;

  static {
    HashMap<String, Class<? extends QParserPlugin>> map = new HashMap<>(30, 1);
    '''第一种类型不包含排序参数:!lucene q.op=AND df=text sort='price asc'}myfield:foo +bar -baz'''
    map.put(LuceneQParserPlugin.NAME, LuceneQParserPlugin.class);
    '''第二种类型包含排序参数:{!lucenePlusSort}myfield:foo +bar -baz;price asc'''
    map.put(OldLuceneQParserPlugin.NAME, OldLuceneQParserPlugin.class);
    .....
    }
}

(2)创建Parser

public class LuceneQParserPlugin extends QParserPlugin {
  public static final String NAME = "lucene";

  @Override
  public QParser createParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) {
    return new LuceneQParser(qstr, localParams, params, req);
  }
}

public class LuceneQParser extends QParser {
  '''SolrQueryParser是JavaCC生成的QueryParser类的子类'''
  SolrQueryParser lparser;
  @Override
  public Query parse() throws SyntaxError {
    String qstr = getString();
    if (qstr == null || qstr.length()==0) return null;

    String defaultField = getParam(CommonParams.DF);
    if (defaultField==null) {
      defaultField = getReq().getSchema().getDefaultSearchFieldName();
    }
    lparser = new SolrQueryParser(this, defaultField);

    lparser.setDefaultOperator
      (QueryParsing.getQueryParserDefaultOperator(getReq().getSchema(),
                                                  getParam(QueryParsing.OP)));
    '''调用父类QueryParser的parse方法解析'''
    return lparser.parse(qstr);
    }
}

(3)JavaCC生成的QueryParser类,Lucene也有同样的类

public class QueryParser extends SolrQueryParserBase implements QueryParserConstants {
    '''在parse()方法调用,此函数是在JavaCC的输入文件XXX.jj中定义,并由JavaCC生成'''
    final public Query TopLevelQuery(String field) throws ParseException, SyntaxError {
  Query q;
    q = Query(field);
    jj_consume_token(0);
    {if (true) return q;}
    throw new Error("Missing return statement in function");
  } 
}

相关文章