文档章节

lucene4.7 正则查询(RegexpQuery)(八)

一枚Sir
 一枚Sir
发布于 2014/04/11 11:02
字数 1439
阅读 2439
收藏 1

今天要分享的是关于lucene中另外一种丰富的查询方式----正则查询,lucene内置了许多的查询API,以及更强大的自定义查询方式的QueryParse,大部分情况下我们使用内置的查询API,基本上就可以满足我们的需求了,但是如果你想更灵活的定制自己的查询或者改写自己的查询API那么你完全可以继承QueryParse类来完成这项工作。 

从某种方式上来说,正则查询(RegexpQuery)跟通配符查询(WildcardQuery)的功能很相似,因为他们都可以完成一样的工作,但是不同的是正则查询支持更灵活定制细化查询,这一点与通配符的泛化是不一样的,而且正则查询天生支持使用强大的正则表达式的来准确匹配一个或几个term,需要注意的是,使用正则查询的字段最好是不分词的,因为分词的字段可能会导致边界问题,从而使查询失败,得不到任何结果,这一点和WildcardQuery效果是一样的。 

下面先来看一下,散仙的测试数据,为了看出分词与不分词给查询造成的影响,散仙的用同样的内容做测试,分词工具使用的是IK的分词器,截图如下: 

在上图中,散仙使用2个字段存储一样的内容,一个是分过词的,一个没分过词的,下面给出使用正则查询的核心代码:

 RegexpQuery query=new RegexpQuery(new Term(field, ".*"+searchStr+".*"));
                  // System.out.println(query.toString());
                  TopDocs s=search.search(query,null, 100);
                //  TopDocs s=search.search(bool,null, 100);
                   System.out.println(s.totalHits);
                  for(ScoreDoc ss:s.scoreDocs){
                         
                         Document docs=search.doc(ss.doc);
                         System.out.println("id=>"+docs.get("id")+"   name==>"+docs.get("bookName")+"   author==>"+docs.get("author"));
                    // System.out.println(docs.get(field));
                     }

下面我们先来测,对不分词的字段的做模糊查询,测试的代码如下:

 dao.testRegQuery("bookName","并发");

结果如下:

命中数据 :2
id=>2   name==>并发数据挑战面临巨大的挑战   author==>并发数据挑战面临巨大的挑战
id=>4   name==>我们的并发数量并秦东亮在不不是很大   author==>我们的并发数量并秦东亮在不不是很大

我们发现它很出色完成了模糊的查询,并且耗时比通配符查询同样的查询条件的耗时要少,下面我们对分词的字段,进行检索,测试代码如下:

 dao.testRegQuery("author","并发");

结果如下:

命中数据 :3
id=>2   name==>并发数据挑战面临巨大的挑战   author==>并发数据挑战面临巨大的挑战
id=>3   name==>the food is perfect!   author==>我们的并发数量并不是很大
id=>4   name==>我们的并发数量并秦东亮在不不是很大   author==>我们的并发数量并秦东亮在不不是很大

我们发现对分词字段的模糊匹配,也同样没问题,下面我们来测下对分词字段的边界查询。代码如下:

 dao.testRegQuery("bookName","e q");
         dao.testRegQuery("bookName","量并");
         System.out.println("===========对比界限=============");
         dao.testRegQuery("author","e q");
         dao.testRegQuery("author","量并");

结果如下:

命中数据 :1
id=>1   name==>the quick brown fox jumps over the lazy dog   author==>the quick brown fox jumps over the lazy dog
命中数据 :1
id=>4   name==>我们的并发数量并秦东亮在不不是很大   author==>我们的并发数量并秦东亮在不不是很大
===========对比界限=============
命中数据 :0
命中数据 :0

由以上结果,我们可以发现分词后的字段,如果在某个字之间被切分成两个term,那么无论你用什么样的方式模糊这两个term边界之间的数据,都查询不到任何结果,而不分词的字段,却能查出来,这是因为,不分词的字段都是作为一个单独的term来处理的,来lucene的内部匹配方式,恰恰又是以term作为最小检索单位的,故能检索到结果,这一点需要我们格外注意,在实现我们的业务时,要根据自己的场景来设计出最优的分词策略。

下面散仙要测的是正则查询的老本行了,使用正则表达式进行查询,代码如下:

     dao.testRegQuery("bookName","[fb]ox");//利用正则式检索

结果如下:

命中数据 :2
id=>1   name==>the quick brown fox jumps over the lazy dog   author==>the quick brown fox jumps over the lazy dog
id=>5   name==>log is small box   author==>log is small box

我们发现含有fox,box的两条数据都被正确的检索出来了,其实检索的条件,在匹配时会被分解成4个条件,分别是,fox,fo,box,bo只要含有这几个term的数据,都会被检索出来,而这一点恰恰省去了,我们在使用其他的查询时使用OR或者AND进行拼接的繁琐,也可以简化成所谓的SQL里面的IN查询,当然使用正则表达式查询方式可以有很多种,在这里只是简单的举了个例子,有兴趣的朋友们,可以自己测测。 

最后在总结一下,1,如果是在不分词的字段里做模糊检索,优先使用正则查询的方式会比其他的模糊方式性能要快。2,在查询的时候,应该注意分词字段的边界问题。3,在使用OR或AND拼接条件查询时或一些特别复杂的匹配时,也应优先使用正则查询。4,大数据检索时,性能尤为重要,注意应避免使用前置模糊的方式,无论是正则查询还是通配符查询。



© 著作权归作者所有

一枚Sir
粉丝 119
博文 209
码字总数 350904
作品 0
朝阳
架构师
私信 提问
Lucene4.3开发之插曲之落寞繁华

本篇是关于lucene中另外一种丰富的查询方式---正则查询,lucene内置了许多的查询api,以及更强大的自定义查询方式的QueryParse,大部分情况下我们使用内置的查询api,基本上就能满足我们的需...

heroShane
2014/02/21
103
0
lucene4.7 高亮功能(八)

高亮功能一直都是全文检索的一项非常优秀的模块,在一个标准的搜索引擎中,高亮的返回命中结果,几乎是必不可少的一项需求,因为通过高亮,我们可以在我们的搜索界面上快速标记出用户的检索关...

一枚Sir
2014/04/11
328
0
Lucene / Solr 4.0 的新特性

Lucene 和 Solr 4.0 是一个非常重要的里程碑,包含大量的新特性以及性能的提升,本文主要介绍值得关注的一些改进。 Lucene: ColumnStrideFields: DocValues 存储在每个文档中,每个文档的域可...

红薯
2012/07/07
8.5K
7
lucene4.7删除索引失败

我使用的是lucene4.7 两个问题: 1 更新索引时不会在原基础上更新,会新增一条。 2 删除索引时删除不掉。 创建IndexWriter的方法 把数据库对象生成索引的方法: 其中LuceneAppUtils是一个工具...

小Y_
2014/06/05
1K
6
lucene4下用MultiFieldQueryParser同时搜索多个field时

因为工作中突然要用到lucene,就到官网上下了lucene4.7的jar包和文档,回头开始学习的时候才发现,网上lucene相关的资料大部分都停留在3.*阶段,于是结合前辈的代码,自己写了下面一个例子,...

一枚Sir
2014/04/10
7.1K
1

没有更多内容

加载失败,请刷新页面

加载更多

JS实现使用Math.random()函数生成n到m间的随机数字

Math.random()函数返回0和1之间的伪随机数,可能为0,但总是小于1,[0,1) 生成n-m,包含n但不包含m的整数: 第一步算出 m-n的值,假设等于w 第二步Math.random()*w 第三步Math.random()*w+n...

张兴华ZHero
26分钟前
4
0
入门了解Service Mesh + Istio?从本文开始

下周六,深圳,阔别已久的线下技术沙龙要和你见面啦! 现场有Rancher Labs研发经理demo刚刚发布的Rancher 2.3中的Istio、Windows容器、集群模板等功能及使用,还有k3s首次线下workshop,由R...

RancherLabs
27分钟前
4
0
Gradle 发布 Jar 到 Archiva 时提示不能 Overwriting released artifacts is not allowed

系统提示错误信息: Received status code 409 from server: Overwriting released artifacts is not allowed. 这是在 Archiva 默认的配置下如果你不是使用 snapshot 配置的话,是不允许对仓...

honeymoose
28分钟前
4
0
二维码插件之qrcode.min.js

文件链接百度云地址 https://pan.baidu.com/s/1nWiBuT4Z7WOAMoUEFL8PZg 入门 http://www.jq22.com/jquery-info294 使用jquery.qrcode.min.js实现前台二维码生成(带Logo) https://blog.csd......

木九天
38分钟前
3
0
开源 java CMS - FreeCMS2.8 自定义标签 commentPage

项目地址:http://www.freeteam.cn/ commentPage 根据参数提取评论对象。 参数 说明 siteid 站点id objtype 评论对象类型 objid 评论对象id membername 会员名称 isanonymous 是否匿名 1是 ...

freeteam
38分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部