本文要描述的是solr的查詢插件,該查詢插件目的用於生成Lucene的查詢Query,相似於查詢條件表達式,與solr查詢插件相關UML類圖以下:html
若是咱們強行將上面的類圖歸入某種設計模式語言的話,本人姑且將之納入橋接模式(Bridge)吧;QParserPlugin插件的行爲依賴於QParser的具體類型web
QParserPlugin爲抽象類,職責爲建立QParser類型對象apache
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對象app
QParser抽象類,其中的靜態方法getParser獲取具體的QParser類型對象供RequestHandler處理器調用ide
/** 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的部分方法)post
--------------------------------------------------------------------------- ui
本系列solr&lucene3.6.0源碼解析系本人原創 this
轉載請註明出處 博客園 刺蝟的溫馴 spa
本人郵箱: chenying998179#163.com (#改成@)