Solr源码解析之一 -- 查询解析器QueryParser

x33g5p2x  于2021-12-20 转载在 其他  
字(3.1k)|赞(0)|评价(0)|浏览(503)
  • 查询解析器注册
  • 查询解析

查询解析器注册

(1)SolrCore构造函数中调用QParserPlugin的init方法注册各种Parser插件

qParserPlugins.init(createInstances(QParserPlugin.standardPlugins), this);

(2)QParserPlugin中调用绑定Parser名字和实例

public abstract class QParserPlugin implements NamedListInitializedPlugin, SolrInfoMBean {

    public static final Map<String, Class<? extends QParserPlugin>> standardPlugins;

  static {
    HashMap<String, Class<? extends QParserPlugin>> map = new HashMap<>(30, 1);
    map.put(LuceneQParserPlugin.NAME, LuceneQParserPlugin.class);
    map.put(OldLuceneQParserPlugin.NAME, OldLuceneQParserPlugin.class);
    map.put(FunctionQParserPlugin.NAME, FunctionQParserPlugin.class);
    map.put(PrefixQParserPlugin.NAME, PrefixQParserPlugin.class);
    map.put(BoostQParserPlugin.NAME, BoostQParserPlugin.class);
    map.put(DisMaxQParserPlugin.NAME, DisMaxQParserPlugin.class);
    map.put(ExtendedDismaxQParserPlugin.NAME, ExtendedDismaxQParserPlugin.class);
    map.put(FieldQParserPlugin.NAME, FieldQParserPlugin.class); 
    map.put(SimpleQParserPlugin.NAME, SimpleQParserPlugin.class);
    map.put(ComplexPhraseQParserPlugin.NAME, ComplexPhraseQParserPlugin.class);
    ......
    standardPlugins = Collections.unmodifiableMap(map);
  }
}

查询解析

(1)在组件QueryComponent的prepare()方法中,根据查询语句确定查询解析器:

public class QueryComponent extends SearchComponent {
  public static final String COMPONENT_NAME = "query";
  public void prepare(ResponseBuilder rb) throws IOException
  {

    '''省略...'''
    '''获取默认的parser'''
    String defType = params.get(QueryParsing.DEFTYPE, QParserPlugin.DEFAULT_QTYPE);    

    try {
      '''调用QParser的getParser方法'''
      QParser parser = QParser.getParser(rb.getQueryString(), defType, req);
      '''调用查询解析器解析查询,返回Lucene的Query子类对象'''
      Query q = parser.getQuery();
      if (q == null) {
        // normalize a null query to a query that matches nothing
        q = new MatchNoDocsQuery();
      }
      '''省略.....'''
    }
}

(2)QParser的getParser方法

public static QParser getParser(String qstr, String defaultParser, SolrQueryRequest req) throws SyntaxError {

    ......
    String parserName;

    if (localParams == null) {
      parserName = defaultParser;
    } else {
      parserName = localParams.get(QueryParsing.TYPE,defaultParser);
      qstr = localParams.get("v");
    }

    parserName = parserName==null ? QParserPlugin.DEFAULT_QTYPE : parserName;

    '''根据名字在map中查询初始化时注册的解析器插件'''
    QParserPlugin qplug = req.getCore().getQueryPlugin(parserName);
    '''创建具体的解析器'''
    QParser parser =  qplug.createParser(qstr, localParams, req.getParams(), req);

    parser.stringIncludingLocalParams = stringIncludingLocalParams;
    parser.valFollowedParams = valFollowedParams;
    parser.localParamsEnd = localParamsEnd;
    return parser;
  }

(3)QParser的getQuery方法解析query并返回Lucene的Query类对象

public abstract class QParser {
    '''在此,只有第一次调用时才解析,然后会缓存解析结果以备后用'''
    public Query getQuery() throws SyntaxError {
    if (query==null) {
      '''调用parse()返回Query对象'''
      query=parse();

      if (localParams != null) {
        String cacheStr = localParams.get(CommonParams.CACHE);
        if (cacheStr != null) {
          if (CommonParams.FALSE.equals(cacheStr)) {
            extendedQuery().setCache(false);
          } else if (CommonParams.TRUE.equals(cacheStr)) {
          '''缓存Query'''
            extendedQuery().setCache(true);
          } else if ("sep".equals(cacheStr)) {
            extendedQuery().setCacheSep(true);
          }
        }

        int cost = localParams.getInt(CommonParams.COST, Integer.MIN_VALUE);
        if (cost != Integer.MIN_VALUE) {
          extendedQuery().setCost(cost);
        }
      }
    }
    return query;
  }
}

相关文章