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 ...
随机推荐
- APP长时间处于后台,再次调用时提示用户重新登录
第一步:当应用被处于后台时,调用计时器的start()方法,开始计时 在所有Activity继承的BaseSwiBackAct中的 public void onStop() { EventBus.ge ...
- 编写利用Fragment创建新闻列表
编写利用Fragment创建新闻列表 1.创建新闻实体类News,代码如下: public class News { private String title; private String co ...
- 【SQL Server】SQL与Excel的数据互通导入导出
转载至:http://jingyan.baidu.com/article/73c3ce28c839b7e50243d950.html
- iOS中的设计模式
一. MVC MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数据.界面显示分离 ...
- Scene is unreachable due to lack of entry points and does not have an identifier for runtime access
使用Storyboard时出现以下警告: warning: Unsupported Configuration: Scene is unreachable due to lack of entry p ...
- [技术翻译]Guava官方文档Ordering
关于排序 Guava的链式比较器 例子 assertTrue(byLengthOrdering.reverse().isOrdered(list)); 梗概 Ordering是Guava的链式比较器类 ...
- 对于HttpContext.Current的一点理解
string[] userInfomationSplits = HttpContext.Current.User.Identity.Name.Split(new string[] { "\\ ...
- css3之box-sizing
css盒子模型中包括几种重要的属性,包括margin.border.padding以及content.但浏览器对其盒子模型的解释则有所不痛,启用标准模式还是IE(怪)模式是与当前页面的文档声明相关的. ...
- Linq介绍
什么是LINQ? LINQ全称Language Integrated Query,中文翻译"语言集成查询".在.NET框架中,大致使用三大组件实现这个封装,分别 LINQ to O ...
- phpMemcache消息队列类
<?php /** * Memcache 消息队列类 */ class QMC { const PREFIX = 'ASDFASDFFWQKE'; /** * 初始化 mc * @staticv ...