本文要描述的是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

solr&lucene3.6.0源码解析(四)的更多相关文章

  1. solr&lucene3.6.0源码解析(三)

    solr索引操作(包括新增 更新 删除 提交 合并等)相关UML图如下 从上面的类图我们可以发现,其中体现了工厂方法模式及责任链模式的运用 UpdateRequestProcessor相当于责任链模式 ...

  2. solr&lucene3.6.0源码解析(二)

    上文描述了solr3.6.0怎么采用maven管理的方式在eclipse中搭建开发环境,在solr中,为了提高搜索性能,采用了缓存机制,这里描述的是LRU缓存,这里用到了 LinkedHashMap类 ...

  3. solr&lucene3.6.0源码解析(一)

      本文作为系列的第一篇,主要描述的是solr3.6.0开发环境的搭建   首先我们需要从官方网站下载solr的相关文件,下载地址为http://archive.apache.org/dist/luc ...

  4. AFNetworking2.0源码解析<四>

    结构 AFURLResponseSerialization负责解析网络返回数据,检查数据是否合法,把NSData数据转成相应的对象,内置的转换器有json,xml,plist,image,用户可以很方 ...

  5. AFNetworking (3.1.0) 源码解析 <四>

    这次主要看一下文件夹Security中的类AFSecurityPolicy----安全策略类. AFSecurityPolicy主要的作用是验证HTTPS请求证书的有效性,在iOS9之后,默认不能发送 ...

  6. Sentinel源码解析四(流控策略和流控效果)

    引言 在分析Sentinel的上一篇文章中,我们知道了它是基于滑动窗口做的流量统计,那么在当我们能够根据流量统计算法拿到流量的实时数据后,下一步要做的事情自然就是基于这些数据做流控.在介绍Sentin ...

  7. Heritrix 3.1.0 源码解析(三十七)

    今天有兴趣重新看了一下heritrix3.1.0系统里面的线程池源码,heritrix系统没有采用java的cocurrency包里面的并发框架,而是采用了线程组ThreadGroup类来实现线程池的 ...

  8. Android事件总线(二)EventBus3.0源码解析

    1.构造函数 当我们要调用EventBus的功能时,比如注册或者发送事件,总会调用EventBus.getDefault()来获取EventBus实例: public static EventBus ...

  9. apache mina2.0源码解析(一)

    apache mina是一个基于java nio的网络通信框架,为TCP UDP ARP等协议提供了一致的编程模型:其源码结构展示了优秀的设计案例,可以为我们的编程事业提供参考. 依照惯例,首先搭建a ...

随机推荐

  1. Git常用命令整理

    .初始化一个Git仓库:git init 2.添加文件到Git仓库: git add <file> 添加文件到暂存区 git commit 把文件提交到版本仓库 3.查看工作区状态:git ...

  2. HTML5 ---localStorage

    HTML5中提供了localStorage对象可以将数据长期保存在客户端,直到人为清除. localStorage提供了几个方法: 1.存储:localStorage.setItem(key,valu ...

  3. C# 根据前台校验的值,决定是否执行后台方法

    <asp:Button ID="Add" runat="server" Text="加入" class="add" ...

  4. 转:union和union all的区别

    Union因为要进行重复值扫描,所以效率低.如果合并没有刻意要删除重复行,那么就使用Union All  两个要联合的SQL语句 字段个数必须一样,而且字段类型要“相容”(一致): 如果我们需要将两个 ...

  5. SAP 采购订单行项目中科目分配被隐藏,发现行项目设置中显示字段长度为0

    1.sm30 维护 视图 TCVIEW 修改对应字段的显示长度

  6. orm获取关联表里的属性值

    ORM——关系对象模型 laravel中的Eloquent ORM用于和数据表互动,其中每个数据库表会和一个对应的「模型」互动,想要了解请查看官方文档或自行百度.获取关联表里的属性值代码如下: /** ...

  7. DSP(2) -- 离散时间信号的序列运算

    1.信号相加:这是一种对应的样本与样本之间的相加. 在Matlab中它可用算术运算符“+”实现,然后x1和x2的长度必须相等.如果序列不等,或者长度虽然相等但采样的位置不同,就不能用运算符“+”了.我 ...

  8. CentOS6系统openssl生成证书和自签证书

    CentOS6系统openssl生成证书和自签证书的过程,记录一下,本文基于CentOS 6 64bit.$ yum install openssl openssl-devel 1,生成服务器端的私钥 ...

  9. IE6的连接数限制问题

    今天解决了一个bug.看似是UI的bug,最后发现IE的设置问题(严格来说,IE6这么做没有问题,因为HTTP协议的规范如此). 先描述一下问题: 有一个页面管理Job,选中一些Job可以Run,每次 ...

  10. Crystal Reports拉报表报错:Error detected by database DLL

    问题描述: 最近在使用Crystal Reports打印报表时,提示错误信息:"Error detected by database DLL." 如下图: 经查找,是因为数据库名称 ...