zoukankan      html  css  js  c++  java
  • solr&lucene3.6.0源码解析(四)

    本文要描述的是solr的查询插件,该查询插件目的用于生成Lucene的查询Query,类似于查询条件表达式,与solr查询插件相关UML类图如下:

    如果我们强行将上面的类图纳入某种设计模式语言的话,本人姑且将之归入桥接模式(Bridge)吧;QParserPlugin插件的行为依赖于QParser的具体类型

    QParserPlugin为抽象类,职责为创建QParser类型对象

    package org.apache.solr.search;
    
    import org.apache.solr.common.params.SolrParams;
    import org.apache.solr.request.SolrQueryRequest;
    import org.apache.solr.util.plugin.NamedListInitializedPlugin;
    
    public abstract class QParserPlugin implements NamedListInitializedPlugin {
      /** internal use - name of the default parser */
      public static String DEFAULT_QTYPE = LuceneQParserPlugin.NAME;
    
      /** internal use - name to class mappings of builtin parsers */
      public static final Object[] standardPlugins = {
        LuceneQParserPlugin.NAME, LuceneQParserPlugin.class,
        OldLuceneQParserPlugin.NAME, OldLuceneQParserPlugin.class,
        FunctionQParserPlugin.NAME, FunctionQParserPlugin.class,
        PrefixQParserPlugin.NAME, PrefixQParserPlugin.class,
        BoostQParserPlugin.NAME, BoostQParserPlugin.class,
        DisMaxQParserPlugin.NAME, DisMaxQParserPlugin.class,
        ExtendedDismaxQParserPlugin.NAME, ExtendedDismaxQParserPlugin.class,
        FieldQParserPlugin.NAME, FieldQParserPlugin.class,
        RawQParserPlugin.NAME, RawQParserPlugin.class,
        TermQParserPlugin.NAME, TermQParserPlugin.class,
        NestedQParserPlugin.NAME, NestedQParserPlugin.class,
        FunctionRangeQParserPlugin.NAME, FunctionRangeQParserPlugin.class,
        SpatialFilterQParserPlugin.NAME, SpatialFilterQParserPlugin.class,
        SpatialBoxQParserPlugin.NAME, SpatialBoxQParserPlugin.class,
      };
    
      /** return a {@link QParser} */
      public abstract QParser createParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req);
    }

    LuceneQParserPlugin类继承自QParserPlugin抽象类,为Solr3.6.0的默认QParserPlugin插件

    /**
     * Parse Solr's variant on the Lucene QueryParser syntax.
     * <br>Other parameters:<ul>
     * <li>q.op - the default operator "OR" or "AND"</li>
     * <li>df - the default field name</li>
     * </ul>
     * <br>Example: <code>{!lucene q.op=AND df=text sort='price asc'}myfield:foo +bar -baz</code>
     */
    public class LuceneQParserPlugin extends QParserPlugin {
      public static String NAME = "lucene";
    
      public void init(NamedList args) {
      }
    
      @Override
      public QParser createParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) {
        return new LuceneQParser(qstr, localParams, params, req);
      }
    }
    
    class LuceneQParser extends QParser {
      SolrQueryParser lparser;
    
      public LuceneQParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) {
        super(qstr, localParams, params, req);
      }
    
    
      @Override
      public Query parse() throws ParseException {
        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);
    
        // these could either be checked & set here, or in the SolrQueryParser constructor
        String opParam = getParam(QueryParsing.OP);
        if (opParam != null) {
          lparser.setDefaultOperator("AND".equals(opParam) ? QueryParser.Operator.AND : QueryParser.Operator.OR);
        } else {
          // try to get default operator from schema
          QueryParser.Operator operator = getReq().getSchema().getSolrQueryParser(null).getDefaultOperator();
          lparser.setDefaultOperator(null == operator ? QueryParser.Operator.OR : operator);
        }
    
        return lparser.parse(qstr);
      }
    
    
      @Override
      public String[] getDefaultHighlightFields() {
        return lparser == null ? new String[]{} : new String[]{lparser.getField()};
      }
      
    }
    }

    其中LuceneQParser类为LuceneQParserPlugin类的内部类,继承自QParser抽象类,其职责为创建Lucene的Query对象

    QParser抽象类,其中的静态方法getParser获取具体的QParser类型对象供RequestHandler处理器调用

    /** Create a <code>QParser</code> to parse <code>qstr</code>,
       * assuming that the default query type is <code>defaultType</code>.
       * The query type may be overridden by local parameters in the query
       * string itself.  For example if defaultType=<code>"dismax"</code>
       * and qstr=<code>foo</code>, then the dismax query parser will be used
       * to parse and construct the query object.  However
       * if qstr=<code>{!prefix f=myfield}foo</code>
       * then the prefix query parser will be used.
       */
      public static QParser getParser(String qstr, String defaultType, SolrQueryRequest req) throws ParseException {
        // SolrParams localParams = QueryParsing.getLocalParams(qstr, req.getParams());
    
        String stringIncludingLocalParams = qstr;
        SolrParams localParams = null;
        SolrParams globalParams = req.getParams();
        boolean valFollowedParams = true;
        int localParamsEnd = -1;
    
        if (qstr != null && qstr.startsWith(QueryParsing.LOCALPARAM_START)) {
          Map<String, String> localMap = new HashMap<String, String>();
          localParamsEnd = QueryParsing.parseLocalParams(qstr, 0, localMap, globalParams);
    
          String val = localMap.get(QueryParsing.V);
          if (val != null) {
            // val was directly specified in localParams via v=<something> or v=$arg
            valFollowedParams = false;
          } else {
            // use the remainder of the string as the value
            valFollowedParams = true;
            val = qstr.substring(localParamsEnd);
            localMap.put(QueryParsing.V, val);
          }
          localParams = new MapSolrParams(localMap);
        }
    
    
        String type;
        
        if (localParams == null) {
          type = defaultType;
        } else {
          type = localParams.get(QueryParsing.TYPE,defaultType);
          qstr = localParams.get("v");
        }
    
        type = type==null ? QParserPlugin.DEFAULT_QTYPE : type;
    
        QParserPlugin qplug = req.getCore().getQueryPlugin(type);
        QParser parser =  qplug.createParser(qstr, localParams, req.getParams(), req);
    
        parser.stringIncludingLocalParams = stringIncludingLocalParams;
        parser.valFollowedParams = valFollowedParams;
        parser.localParamsEnd = localParamsEnd;
        return parser;
      }

    SolrQueryParser继承自Lucene的QueryParser,职责为解析查询表达式,生成查询Query对象(重写了父类QueryParser的部分方法)

    --------------------------------------------------------------------------- 

    本系列solr&lucene3.6.0源码解析系本人原创 

    转载请注明出处 博客园 刺猬的温驯 

    本人邮箱: chenying998179#163.com (#改为@)

    本文链接http://www.cnblogs.com/chenying99/p/3508509.html

  • 相关阅读:
    查找oracle数据文件、表空间的位置
    select into 给多变量赋值
    关于Union 中 ORA-12704:字符集不匹配问题的解决
    weblogic线程阻塞性能调优(图解)
    window系统无法访问局域网内文件共享的问题
    查看oracle的sql语句历史记录和锁表的情况
    <c:forEach>标签的使用 JSTL
    CAS服务下单点登录(服务端与客户端)
    cas 配置数据源 , 解决CAS 不支持你提供的凭证 .
    信号量通俗释义
  • 原文地址:https://www.cnblogs.com/chenying99/p/3508509.html
Copyright © 2011-2022 走看看