Lucene自定义扩展QueryParser
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的更多相关文章
- SharePoint 2013 自定义扩展菜单
在对SharePoint进行开发或者功能扩展的时候,经常需要对一些默认的菜单进行扩展,以使我们开发的东西更适合SharePoint本身的样式.SharePoint的各种功能菜单,像网站设置.Ribbo ...
- SharePoint 2013 自定义扩展菜单(二)
接博文<SharePoint 2013 自定义扩展菜单>,多加了几个例子,方便大家理解. 例七 列表设置菜单扩展(listedit.aspx) 扩展效果 XML描述 <CustomA ...
- WCF自定义扩展,以实现aop!
引用地址:https://msdn.microsoft.com/zh-cn/magazine/cc163302.aspx 使用自定义行为扩展 WCF Aaron Skonnard 代码下载位置: S ...
- Jquery自定义扩展方法(二)--HTML日历控件
一.概述 研究了上节的Jquery自定义扩展方法,自己一直想做用jquery写一个小的插件,工作中也用到了用JQuery的日历插件,自己琢磨着去造个轮子--HTML5手机网页日历控件,废话不多说,先看 ...
- Silverlight实例教程 - 自定义扩展Validation类,验证框架的总结和建议(转载)
Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础 ...
- jQuery 自定义扩展,与$冲突处理
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- SparkContext自定义扩展textFiles,支持从多个目录中输入文本文件
需求 SparkContext自定义扩展textFiles,支持从多个目录中输入文本文件 扩展 class SparkContext(pyspark.SparkContext): def ...
- 基于 HtmlHelper 的自定义扩展Container
基于 HtmlHelper 的自定义扩展Container Intro 基于 asp.net mvc 的权限控制系统的一部分,适用于对UI层数据呈现的控制,基于 HtmlHelper 的扩展组件 Co ...
- 第十三节:HttpHander扩展及应用(自定义扩展名、图片防盗链)
一. 自定义扩展名 1. 前言 凡是实现了IHttpHandler接口的类均为Handler类,HttpHandler是一个HTTP请求的真正处理中心,在HttpHandler容器中,ASP.NET ...
随机推荐
- 四、分离T4引擎
在前几篇文章中,我使用大量的篇幅来介绍T4在VisualStudio中如何使用.虽然在一定程度上可以提高我们的工作效率,但并没有实质上的改变.不过从另一方面来说,我们确实了解到了T4的强大. ...
- jsp中文乱码终极解决方法(转)
一, 找出问题的根源乱码可能出现的地方: jsp页面中 jsp页面之间相互传参的参数 与数据库中数据的存取 基本归纳为以上几种. 二, 寻找解决方案 出现在jsp页面中,是由于没有设置jsp页面的中文 ...
- UITextView textViewShouldEndEditing
最近做到UITextView, 在取消键盘事件上我以为和UITextField差不多,于是我这样写: UITextView *textView = [[UITextView alloc] initWi ...
- cas sso单点登录系列6_cas单点登录防止登出退出后刷新后退ticket失效报500错
转(http://blog.csdn.net/ae6623/article/details/9494601) 问题: 我登录了client2,又登录了client3,现在我把client2退出了,在c ...
- 跟我学android-Android应用结构分析(四)
自动生成的R.java文件说明 public final class R { public static final class attr { } public static final class ...
- static_cast、const_cast和reinterpret_cast学习
static_cast 任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast.例如,通过将一个运算对象强制转换成double类型就能表达式浮点数除法: //进行强制类 ...
- Javascript模块化编程:模块的写法
声明:本文转载自:阮一峰的网络日志,原文地址http://www.ruanyifeng.com/blog/2012/10/javascript_module.html,http://www.ruany ...
- js学习笔记之:时间(二)
今天来了解一下js中定时器的两种用法.js中包括2种定时器,分别是: 间隔型定时器:setInterval(开) clearInterval (关) 延 ...
- 16 3Sum Closest(输出距离target最近的三个数的和Medium)
题目意思:给一个数组,给一个target,找三个数的和,这个和要与target距离最近,输出这个和 思路:这个题比3sum要稍微简单一点,如果需要优化,也可以去重,不过因为结果唯一,我没有去重. mi ...
- 学习Cassandra资料的一些整理
Cassandra note: 依赖:需要java 8 (http://www.oracle.com/technetwork/java/javase/downloads/index.html) 数据模 ...