Lucene版本:4.10.2

在使用lucene的时候,不可避免的需要扩展lucene的相关功能来实现业务的需要,比如搜索时,需要在满足一个特定范围内的document进行搜索,如年龄在20和30岁之间的document中搜索并排序。其实lucene自带的NumericRangeQuery类已经能实现这个功能了,如下:

public void testInclusive() throws Exception {

    Directory dir = FSDirectory(---);

    IndexSearcher searcher = new IndexSearcher(dir);

    NumericRangeQuery query = NumericRangeQuery.newIntRange("age",20,30,true,true);

    TopDocs matches = searcher.search(query,10);

}

这个是通过lucene内置的query类型来进行搜索,但是这样使用起来的缺点就是无法再搜索期间生成对应的NumericRangeQuery实例,如比如直接在搜索的时候传入搜索text: age:[20 TO 30],这样就可以动态的使用范围搜索,更为灵活,那么要是实现这个功能,我们就需要自定义QueryParser了。

QueryParser,故名思议,就是讲前台传入的查询条件,解析为Query实例,从而进行查询,所以简单的说,我们需要自定义一个NumericRangeQueryParser,用来实现,从 age:[20 TO 30] 转化为

NumericRangeQuery query = NumericRangeQuery.newIntRange("age",20,30,true,true); 

的一个Query实例。

在lucene中扩展QueryParser是比较简单的,我们可以直接继承QueryParser类,然后实现特定的方法就可以了(查询age在20至30岁的记录):

        //自定义queryParser
class NumericRangeQueryParser extends QueryParser { /**
* @param arg0
*/
protected NumericRangeQueryParser(String field,Analyzer analyzer) {
//调用父类的构造方法
super(field,analyzer);
// TODO Auto-generated constructor stub
} //获取query实例的方法
public Query getRangeQuery(String field,String part1,String part2,boolean startInclusive,boolean endInclusive) throws ParseException {
//调用父类的getRangeQuery方法获取query实例
TermRangeQuery query = (TermRangeQuery) super.getRangeQuery方法获取query实例(field, part1, part2, startInclusive,endInclusive);
//如果是搜索age Field
if("age".equals(field)) {
System.out.println(query.getLowerTerm().utf8ToString());
System.out.println(query.getUpperTerm().utf8ToString()); //按照业务需求处理query生成新的query实例并返回
return NumericRangeQuery.newDoubleRange("price", Double.parseDouble(query.getLowerTerm().utf8ToString()),
Double.parseDouble(query.getUpperTerm().utf8ToString()), query.includesLower(), query.includesUpper());
} else {
return query;
}
} }

其实代码很简单,因为我只是将范围查询的上下限从Int类型格式化成Double类型。其中最重要的一条代码是:

NumericRangeQuery.newDoubleRange("price", Double.parseDouble(query.getLowerTerm().utf8ToString()),

                        Double.parseDouble(query.getUpperTerm().utf8ToString()), query.includesLower(), query.includesUpper());

NumericRangeQuery.newDoubleRange是调用了lucene自带的方法来生成相应的query实例,在这里是浮点数范围查询Query实例。其中参数的解释:

query.getLowerTerm().utf8ToString():getLowerTerm是指获取范围查询中的下限,在这里是20。getLowerTerm()返回一个BytesRef对象,lucene自定义的一种对象,我们需要转换成String类型再转成Double类型的对象,传给NumericRangeQuery.newDoubleRange方法,在这里我一开始想到的是toString方法,结果老是报错,最后查看源码才知道应该使用utf8ToString()方法,它会将BytesRef转成utf8编码的String对象。

public String utf8ToString()

Interprets stored bytes as UTF8 bytes, returning the resulting string

query.getUpperTerm().utf8ToString():与query.getLowerTerm().utf8ToString()同理,获取范围查询中的上限,在这里是30

query.includesLower()和query.includesUpper():是否包含临界值,在这里值是否包含年龄为20和30岁的记录,即[20,30]或[20,30)…

下面我没来测试NumericRangeQueryParser:

    public static void main(String[] args) throws IOException, ParseException {
String expression = "age:[10 TO 20]";
Analyzer analyzer = new StandardAnalyzer();
QueryParser parser = new QueryParser("age",analyzer);
Query query = parser.parse(expression); QueryParser testParser = kscSearch.new NumericRangeQueryParser("age",analyzer);
Query testQuery = testParser.parse(expression); System.out.println(expression + " parser to " + query);
System.out.println(expression + " parser to " + testQuery);
}

测试结果如下:

age:[10 TO 20] parser to age:[10 TO 20]

age:[10 TO 20] parser to price:[10.0 TO 20.0]

可以看到使用NumericRangeQueryParser后,10和20都变成了浮点数。

相应的我们可以自定义日期QueryParser或者是更为复杂的QueryParser。不过从这个简单的NumericRangeQueryParser中我们可以看到QueryParser的原理,就是讲给定的查询字符串解析生成Lucene能识别的Query实例,从而进行查询,我们这里是使用了Lucene内置的NumericRangeQuery扩展QueryParser,如果有需要,甚至可以自定义NumericRangeQuery。

Lucene自定义扩展QueryParser的更多相关文章

  1. SharePoint 2013 自定义扩展菜单

    在对SharePoint进行开发或者功能扩展的时候,经常需要对一些默认的菜单进行扩展,以使我们开发的东西更适合SharePoint本身的样式.SharePoint的各种功能菜单,像网站设置.Ribbo ...

  2. SharePoint 2013 自定义扩展菜单(二)

    接博文<SharePoint 2013 自定义扩展菜单>,多加了几个例子,方便大家理解. 例七 列表设置菜单扩展(listedit.aspx) 扩展效果 XML描述 <CustomA ...

  3. WCF自定义扩展,以实现aop!

    引用地址:https://msdn.microsoft.com/zh-cn/magazine/cc163302.aspx  使用自定义行为扩展 WCF Aaron Skonnard 代码下载位置: S ...

  4. Jquery自定义扩展方法(二)--HTML日历控件

    一.概述 研究了上节的Jquery自定义扩展方法,自己一直想做用jquery写一个小的插件,工作中也用到了用JQuery的日历插件,自己琢磨着去造个轮子--HTML5手机网页日历控件,废话不多说,先看 ...

  5. Silverlight实例教程 - 自定义扩展Validation类,验证框架的总结和建议(转载)

    Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础 ...

  6. jQuery 自定义扩展,与$冲突处理

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. SparkContext自定义扩展textFiles,支持从多个目录中输入文本文件

    需求   SparkContext自定义扩展textFiles,支持从多个目录中输入文本文件   扩展   class SparkContext(pyspark.SparkContext): def ...

  8. 基于 HtmlHelper 的自定义扩展Container

    基于 HtmlHelper 的自定义扩展Container Intro 基于 asp.net mvc 的权限控制系统的一部分,适用于对UI层数据呈现的控制,基于 HtmlHelper 的扩展组件 Co ...

  9. 第十三节:HttpHander扩展及应用(自定义扩展名、图片防盗链)

    一. 自定义扩展名 1. 前言 凡是实现了IHttpHandler接口的类均为Handler类,HttpHandler是一个HTTP请求的真正处理中心,在HttpHandler容器中,ASP.NET ...

随机推荐

  1. iOS加载启动图的时候隐藏statusbar + 指定启动图显示多少秒

    只需需要在info.plist中加入Status bar is initially hidden 设置为YES 补充一下,现在手机越来越快,在6+下面启动图一闪而过,而美工童鞋辛辛苦苦做的图就看不到鸟 ...

  2. CompareValidator ASP控件

    定义和用法 CompareValidator 控件用于将由用户输入到输入控件的值与输入到其他输入控件的值或常数值进行比较. 注释:如果输入控件为空,则不会调用任何验证函数,并且验证将成功.使用 Req ...

  3. 基于daridus认证的openvpn部署

    基于daridus认证的openvpn部署 安装openvpn 1.安装openvpn依赖包 #yum -y install gcc gcc-c++ #yum -y install openssl o ...

  4. unset() isset() empty difined()操作变量详解

    isset()函数 一般用来检测变量是否设置 格式:bool isset ( mixed var [, mixed var [, ...]] )  功能:检测变量是否设置 返回值:  若变量不存在则返 ...

  5. zend studio设置

    1.字体设置: 第一步:进入设置窗口    windows -> preferences 第二步:进入修改字体的选项卡.    General -> Appearance -> Co ...

  6. error: File not found by glob???

    引发上述问题的几种情形: 1.rpm包的包名中含有“[.]”这类特殊符号; 2.执行rpm -ivh xxxx.rpm时,xxxx包名不存在; 3.rpm包顶层的目录名不存在或者存在问题:     - ...

  7. 总结:ARM逻辑和高级C(朱老师物联网学习)

    开始学习朱老师物联网的视频是国庆节的那几天开始的,刚刚开始的时候是想自己在网上找一些嵌入式方面的视频资料,也找了很多的资料臂如“国嵌视频”“达内的视频”,之后也化了十几块钱在淘宝上面买了几十个G的视频 ...

  8. 希尔排序(Shell's Sort)的C语言实现

    原创文章,转载请注明来自钢铁侠Mac博客http://www.cnblogs.com/gangtiexia 希尔排序(Shell's Sort)又称“缩小增量排序”(Diminishing Incre ...

  9. spring mvc标准项目结构

    src com.xxx.inews.dao com.xxx.inews.dao.impl com.xxx.inews.data.entity com.xxx.inews.data.vo com.xxx ...

  10. 构建高可用web站点学习(一)

    单个服务器如何处理请求 web服务器最简单的形式就是一个程序,它侦听HTTP请求,在收到一个HTTP请求之后做出回复.当然在接收请求后服务器所做的东西是我们关注的焦点.在下文中也会提及到node是如何 ...