关于lucene中另外一种丰富的查询方式----正则查询,lucene内置了许多的查询API,以及更强大的自定义查询方式的QueryParse,大部分情况下我们使用内置的查询API,基本上就可以满足我们的需求了,但是如果你想更灵活的定制自己的查询或者改写自己的查询API那么你完全可以继承QueryParse类来完成这项工作。 从某种方式上来说,正则查询(RegexpQuery)跟通配符查询(WildcardQuery)的功能很相似,因为他们都可以完成一样的工作,但是不同的是正则查询支持更灵活定制细化查询,这一点与通配符的泛化是不一样的,而且正则查询天生支持使用强大的正则表达式的来准确匹配一个或几个term,需要注意的是,使用正则查询的字段最好是不分词的,因为分词的字段可能会导致边界问题,从而使查询失败,得不到任何结果,这一点和WildcardQuery效果是一样的。 下面先来看一下,散仙的测试数据,为了看出分词与不分词给查询造成的影响,散仙的用同样的内容做测试,分词工具使用的是IK的分词器,截图如下: 在上图中,散仙使用2个字段存储一样的内容,一个是分过词的,一个没分过词的,下面给出使用正则查询的核心代码: Java代码 复制代码 收藏代码 1.RegexpQuery query=new RegexpQuery(new Term(field,".*"+searchStr+".*")); 2. // System.out.println(query.toString()); 3. TopDocs s=search.search(query,null,100); 4. // TopDocs s=search.search(bool,100); 5. System.out.println(s.totalHits); 6. for(scoreDoc ss:s.scoreDocs){ 7. 8. Document docs=search.doc(ss.doc); 9. System.out.println("id=>"+docs.get("id")+" name==>"+docs.get("bookName")+" author==>"+docs.get("author")); 10. // System.out.println(docs.get(field)); 11. } 下面我们先来测,对不分词的字段的做模糊查询,测试的代码如下: Java代码 复制代码 收藏代码 1.dao.testRegQuery("bookName","并发"); 结果如下: Java代码 复制代码 收藏代码 1.命中数据 :2 2.id=>2 name==>并发数据挑战面临巨大的挑战 author==>并发数据挑战面临巨大的挑战 3.id=>4 name==>我们的并发数量并秦东亮在不不是很大 author==>我们的并发数量并秦东亮在不不是很大 我们发现它很出色完成了模糊的查询,并且耗时比通配符查询同样的查询条件的耗时要少,下面我们对分词的字段,进行检索,测试代码如下: Java代码 复制代码 收藏代码 1.dao.testRegQuery("author","并发"); 结果如下: Java代码 复制代码 收藏代码 1.命中数据 :3 2.id=>2 name==>并发数据挑战面临巨大的挑战 author==>并发数据挑战面临巨大的挑战 3.id=>3 name==>the food is perfect! author==>我们的并发数量并不是很大 4.id=>4 name==>我们的并发数量并秦东亮在不不是很大 author==>我们的并发数量并秦东亮在不不是很大 我们发现对分词字段的模糊匹配,也同样没问题,下面我们来测下对分词字段的边界查询。代码如下: Java代码 复制代码 收藏代码 1.dao.testRegQuery("bookName","e q"); 2. dao.testRegQuery("bookName","量并"); 3. System.out.println("===========对比界限============="); 4. dao.testRegQuery("author","e q"); 5. dao.testRegQuery("author","量并"); 结果如下: Java代码 复制代码 收藏代码 1.命中数据 :1 2.id=>1 name==>the quick brown fox jumps over the lazy dog author==>the quick brown fox jumps over the lazy dog 3.命中数据 :1 4.id=>4 name==>我们的并发数量并秦东亮在不不是很大 author==>我们的并发数量并秦东亮在不不是很大 5.===========对比界限============= 6.命中数据 :0 7.命中数据 :0 由以上结果,我们可以发现分词后的字段,如果在某个字之间被切分成两个term,那么无论你用什么样的方式模糊这两个term边界之间的数据,都查询不到任何结果,而不分词的字段,却能查出来,这是因为,不分词的字段都是作为一个单独的term来处理的,来lucene的内部匹配方式,恰恰又是以term作为最小检索单位的,故能检索到结果,这一点需要我们格外注意,在实现我们的业务时,要根据自己的场景来设计出最优的分词策略。 下面散仙要测的是正则查询的老本行了,使用正则表达式进行查询,代码如下: Java代码 复制代码 收藏代码 1.dao.testRegQuery("bookName","[fb]ox");//利用正则式检索 结果如下: Java代码 复制代码 收藏代码 1.命中数据 :2 2.id=>1 name==>the quick brown fox jumps over the lazy dog author==>the quick brown fox jumps over the lazy dog 3.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,大数据检索时,性能尤为重要,注意应避免使用前置模糊的方式,无论是正则查询还是通配符查询。

lucene中另外一种丰富的查询方式----正则查询的更多相关文章

  1. ios – 为自定义创建的串行异步队列设置优先级

    如何使用GCD为自定义创建的串行异步队列设置高优先级?如果是这样,什么是替代解决方案?解决方法您的队列仍然是串行的.它只会在高优先级全局并发后台队列的一个插槽中一次执行一项任务.一旦创建,串行队列就不能以任何方式“并发”.同样,如果您创建并发队列并将其设置为以串行队列为目标,则它实际上变为串行.这一切都在manpage中有所涉及.

  2. 零基础从头学习Swift一:Swift环境搭建

    据我初步的了解,苹果的相关开发使用的IDE都是Xcode这个软件,我们通过AppStore下载相关的Xcode软件,我使用的是8.1这个版本。为了以后学习的方便,先创建一个工作空间,打开Xcode软件,如下图我们通过File--New--Workspace创建一个工作空间,命名为swift,路径选择自己的文件夹。点击Next这里项目名喔命名为Swift001,语言选择Swift。我们从左侧目录找到main.swift文件,这里又两行代码:我们点击左上角的运行按钮一个简单的环境就这样完成了,学习还在继续。。

  3. 零基础从头学习Swift二:Swift中的变量和常量

    今天Swift学习继续,这里主要介绍下Swift中的变量和常量,自己对Swift的初步了解,感觉Swift对数据类型的定义有点像JS,都是弱类型的,都是通过var来定义一个变量。Swift中的变量Swift中通过var这个关键字来定义变量,比如以下代码:这里都没有指定变量具体的数据类型,都是自动来做的,如果我们想手动指定变量的具体类型的话,可以通过如下方式:不过看一些资料说不建议这样写,自己也不是太明白。

  4. Lucene在Android中

    我是android和Lucene的新手.我可以在Android列表视图中使用Lucene进行搜索.我已经尝试导入包2.3.2并且还使用了库中的jar文件.但是,SearchFiles.java中存在错误错误是:无法解析java.rmi.Remote类型.它是从.class文件间接引用的.这个文件有可能不存在于android.这是问题吗?解决方法您可能希望在SQLite中使用名为FTS3的本机FullTextSearch功能,该功能在Android中可用,并且速度更快并且使用的内存比DalvikVM下的Ja

  5. 浅谈Swoole并发编程的魅力

    PHP语言是一个短生命周期的Web编程语言,很多PHPer已经形成了fpm下编程的思维定势。实际上在Swoole出现之后,这种串行化编程的模式早已被打破。使用Swoole完全可以轻易实现更灵活的并发编程。

  6. Java正则表达式API边界匹配

    这篇文章主要介绍了Java正则表达式API边界匹配,文章围绕主题展开相应的相关资料,具有一定的参考价值,需要的朋友可以参考一下

  7. Springboot通过lucene实现全文检索详解流程

    Lucene是一个基于Java的全文信息检索工具包,它不是一个完整的搜索应用程序,而是为你的应用程序提供索引和搜索功能。Lucene 目前是 Apache Jakarta 家族中的一个开源项目,也是目前最为流行的基于 Java 开源全文检索工具包

  8. PHP正则替换函数preg_replace()报错:Notice Use of undefined constant的解决方法分析

    这篇文章主要介绍了PHP正则替换函数preg_replace()报错:Notice Use of undefined constant的解决方法,结合具体实例形式分析了preg_replace()报错的原因与相关解决技巧,需要的朋友可以参考下

  9. 多php服务器实现多session并发运行

    由于session的采用,大大方便了web开发员的工作。现在php4也加入session的支持,再度显示出opensource的强大力量。原来设计的静态的唯一的sessionID导致数据混乱。这样,动态生成一个唯一的sessionID成为当务之急。解决办法很简单:我用了php文件名时间戳为唯一的sessionID,这样在我的程序中的每个session就各就各位,不再混乱了。Mysessionname也不能用cookie方式存放,因为多个session肯定会覆盖掉原先的cookie文件。

  10. Java并发程序刺客之假共享的原理及复现

    前段时间在各种社交平台“雪糕刺客”这个词比较火,而在并发程序中也有一个刺客,那就是假共享。本文将通过示例详细讲解假共享的原理及复现,需要的可以参考一下

随机推荐

  1. 法国电话号码的正则表达式

    我正在尝试实施一个正则表达式,允许我检查一个号码是否是一个有效的法国电话号码.一定是这样的:要么:这是我实施的但是错了……

  2. 正则表达式 – perl分裂奇怪的行为

    PSperl是5.18.0问题是量词*允许零空间,你必须使用,这意味着1或更多.请注意,F和O之间的空间正好为零.

  3. 正则表达式 – 正则表达式大于和小于

    我想匹配以下任何一个字符:或=或=.这个似乎不起作用:[/]试试这个:它匹配可选地后跟=,或者只是=自身.

  4. 如何使用正则表达式用空格替换字符之间的短划线

    我想用正则表达式替换出现在带空格的字母之间的短划线.例如,用abcd替换ab-cd以下匹配字符–字符序列,但也替换字符[即ab-cd导致d,而不是abcd,因为我希望]我如何适应以上只能取代–部分?

  5. 正则表达式 – /bb | [^ b] {2} /它是如何工作的?

    有人可以解释一下吗?我在t-shirt上看到了这个:它似乎在说:“成为或不成为”怎么样?我好像没找到’e’?

  6. 正则表达式 – 在Scala中验证电子邮件一行

    在我的代码中添加简单的电子邮件验证,我创建了以下函数:这将传递像bob@testmymail.com这样的电子邮件和bobtestmymail.com之类的失败邮件,但是带有空格字符的邮件会漏掉,就像bob@testmymail也会返回true.我可能在这里很傻……当我测试你的正则表达式并且它正在捕捉简单的电子邮件时,我检查了你的代码并看到你正在使用findFirstIn.我相信这是你的问题.findFirstIn将跳转所有空格,直到它匹配字符串中任何位置的某个序列.我相信在你的情况下,最好使用unapp

  7. 正则表达式对小字符串的暴力

    在测试小字符串时,使用正则表达式会带来性能上的好处,还是会强制它们更快?不会通过检查给定字符串的字符是否在指定范围内比使用正则表达式更快来强制它们吗?

  8. 正则表达式 – 为什么`stoutest`不是有效的正则表达式?

    isthedelimiter,thenthematch-only-onceruleof?PATTERN?

  9. 正则表达式 – 替换..与.在R

    我怎样才能替换..我尝试过类似的东西:但它并不像我希望的那样有效.尝试添加fixed=T.

  10. 正则表达式 – 如何在字符串中的特定位置添加字符?

    我正在使用记事本,并希望使用正则表达式替换在字符串中的特定位置插入一个字符.例如,在每行的第6位插入一个逗号是什么意思?如果要在第六个字符后添加字符,请使用搜索和更换从技术上讲,这将用MatchGroup1替换每行的前6个字符,后跟逗号.

返回
顶部