日常开发中,相信大家经常会用like去匹配一些数据,同时我们也知道,like往往会导致全表扫描,当数据量越来越大的时候,我们会纠结于
数据库的龟速查找,此时我们必须另寻蹊跷,这时lucene就可以大显身手了。
首先我们做一个demo,向数据库中插入10w条数据,总共778m。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5CN3ADM3UjMyITM1AjMxAjMvwVM0cDNxIzLcJTMwIzLcNXZnFWbp9CXt92YuM3ZvxmYuNmLyADMjlGcvw1LcpDc0RHaiojIsJye.png)
接下来,我们搜索下新闻内容中包含“流行”的记录。
mmd,检索一下要78s,是谁都要砸了面前的破机子。
我靠,448ms,顿时78s黯然失色,当然这个时间是不包含"创建索引“的时间,从时间复杂度上来说,这种预加载索引算是常量。
作为入门,简单的介绍下lucene的实现过程,首先lucene主要分成两步:"索引"和"搜索"。
一:索引:
相信大家对索引还是比较熟悉的,lucene能够将我们内容切分成很多词,然后将词作为key,建立“倒排索引”,然后放到索引库中,在上面
的例子中,我们看到了索引过程中使用到了indexwriter,fsdirectory,standardanalyzer,document和field这些类,下面简要分析下。
1:indexwriter
我们看到该类有一个adddocument方法,所以我们认为该类实现了索引的写入操作。
2:fsdirectory
这个就更简单了,提供了索引库的存放位置,比如我们这里的d:\sample,或许有人问,能不能存放在内存中,在强大的lucene面前当然
可以做到,lucene中的ramdirectory就可以实现,当然我们的内存足够大的话,还是可以用内存承载索引库,进而提高搜索的效率。
3:standardanalyzer
这个算是索引过程中最最关键的一步,也是我们使用lucene非常慎重考虑的东西,之所以我们能搜索秒杀,关键在于我们如何将输入的内容
进行何种形式的切分,当然不同的切分形式诞生了不同的分析器,standardanalyzer就是一个按照单字分词的一种分析器,详细的介绍后续文
章分享。
4:document
在上面的例子可以看到,他是承载field的集合,然后添加到indexwriter中,有点类似表中的行的概念。
5: field
提供了对要分析的字段进行何种处理,以kv形式呈现。
①:field.store.yes, field.index.not_analyzed 表示对索引字段采取:原样保存并且不被standardanalyzer进行切分。
②: field.store.no, field.index.analyzed 不保存但是要被standardanalyzer切分。
二:搜索
这个比较容易,根据我们输入的词lucene能够在索引库中快速定位到我们要找的词,同样我们可以看到indexsearcher,queryparser,hits。
1:indexsearcher
这个我们可以理解成以只读的形式打开由indexwriter创建的索引库,search给queryparser提供了查询的桥梁。
2:queryparser
这玩意提供了一个parse方法能够将我们要查找的词转化为lucene能够理解了查询表达式。
3:hits
这个就是获取匹配结果的一个指针,优点类似c#中的延迟加载,目的都是一样,提高性能。