Lucene学习:介绍和搭建项目

1. 全文检索介绍

1.1. 全文检索是什么

终于有时间来介绍一下之前学过的全文检索了。按照百度上的解释,全文检索的概念是:

全文检索是计算机程序通过扫描文章中的每一个词,对每一个词建立一个索 引,指明该词在文章中出现的次数和位置。当用户查询时根据建立的索引查 找,类似于通过字典的检索字表查字的过程。

通俗来说,全文检索就是分解查询条件的信息,然后查询出跟分解查询条件后的信息匹配的信息记录。最好的例子就是百度:

 

通过将查询条件“在你来之前我们已经是冠军了”分解成“在你来之前”、“已经是”、“冠军了”等信息再去匹配相关信息查询出来。这种搜索方式就是全文检索。

1.2. 全文检索和数据库查询有什么不同

看到这里,也许会有人会说全文检索和数据库查询都是查询,应该差别不大吧!

这其中的差别可以用下面表情包来表达了。

 Lucene学习:介绍和搭建项目Lucene学习:介绍和搭建项目Lucene学习:介绍和搭建项目Lucene学习:介绍和搭建项目Lucene学习:介绍和搭建项目

 

 

 如果数据库能够很好地解决全文检索的问题,那就应该不会有lucene的出现了。数据库查询的方式比较古板,最多就是能前后匹配,限制比较大。

select xxx from xxx where xxx like ‘%在你来之前我们已经是冠军了%’

这样的语句查询条件多一个字和少一个子的查询结果差别比较大。而且当数据比较大,遇到上千万过亿的数据的时候,数据库查询的效率会比较低。

而全文检索恰好就是为了应对这种情况而诞生的。

全文检索可以处理上亿的数据而保持效率,并且搜索出来的结果会更智能。

2. Lucene介绍

官网:http://lucene.apache.org/

Lucene是什么呢?为什么要介绍它呢?

因为Lucene是一套用于全文检索和搜寻的开源程序库,由Apache软件基金会支持和提供。Lucene提供了一个简单却强大的应用程序接口(API),能够做全文索引和搜寻,在Java开发环境里Lucene是一个成熟的免费开放源代码工具。

当然也可以用Solr和Elasticsearch来开发,但这里讲的是用lucene来开发,其它的就不展开了。不过值得一提的是,Solr和Elasticsearch都是基于Lucene开发的搜索引擎产品。

2.1. Lucene实现全文检索原理

这里简单说一下Lucene实现全文检索的原理:

Lucene技术可以类比构造一个数据库,但lucene是通过获取文本的信息,通过分词器分词建立索引构成索引库(类比数据库)。然后就可以通过lucene的查询对象去建立好索引的数据或者文档了。lucene中的一个document对应数据库的一条记录,而一个feild则对应数据库的一个字段。

注意:lucene适合对纯文本(txt)建立索引,理论上对doc,ppt,cls等也可以,但测试结果不佳。对pdf等文件应该使用poi等工具进行数据转换,再建立索引。

 Lucene学习:介绍和搭建项目

该图参考来自:https://blog.csdn.net/weixin_42633131/article/details/82873731

2.2. 分词器

分词器是lucene中用来对文本信息进行信息提取,建立索引的算法器。虽然lucene本身自备了几个分词器,但是只对英文有效,关于中文的效果都不算好。因此这里推荐一个中文分词器:IKAnalyzer

2.2.1. IKAnalyzer分词器

IK作为比较老派,且比较出名的中文分词器。分词效果好,并且可以拓展新词是个比较好的选择。

缺点是自从更新到2012版本后,就停止更新了。尽管有个说法是,IK分词器已经到达中文分词的瓶颈了,就是说这个产品已经很完美了,不需要再更新,后面无非是在拓展文件里面添加新词就可以了。但是,IK分词器只支持Lucene4版本,不支持后面版本的lucene, 若要支持高版本的lucene则需要对IK分词器进行源码修改。

最近在github看到有关的更新,详情可以查看:https://github.com/magese/ik-analyzer-solr

3. java引入Lucene8.1.0

3.1. 导入相关包

到官网下载Lucene的jar包:http://lucene.apache.org/

到github下载IKAnalyzer的jar包

需要导入的jar包如下:

 Lucene学习:介绍和搭建项目

同时也要引入IKAnalyzer的相关文件:

IKAnalyzer.cfg.xml

ext.dic

stopword.dic

3.1.1. IKAnalyzer.cfg.xml

IKAnalyzer.cfg.xml文件要放在src目录下,否则分词器会无法获取到拓展词或者停止词。该文件配置ext.dic和stopword.dic这两个文件的路径。

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 
 3 <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">  
 4 
 5 <properties>  
 6 
 7 <comment>IK Analyzer 扩展配置</comment>
 8 
 9 <!--用户可以在这里配置自己的扩展字典 -->
10 
11 <entry key="ext_dict">ext.dic;</entry> 
12 
13 <!--用户可以在这里配置自己的扩展停止词字典-->
14 
15 <entry key="ext_stopwords">stopword.dic;</entry> 
16 
17 </properties>

3.1.2. ext.dic

ext.dic是拓展词库,分词器会对拓展词库里面的词语不再分词。

3.1.3. stopword.dic

stopword.dic是停止词库,分词器会对将与停止词库匹配的词语过滤掉。

3.1.4. 分词测试

这里可以写一个方法测试分词效果:

 1 import java.io.IOException;
 2 import java.io.StringReader;
 3 import org.wltea.analyzer.core.IKSegmenter;
 4 import org.wltea.analyzer.core.Lexeme;
 5 
 6 public class IkanalyzerTest {
 7 
 8 private static void analysisString() {
 9 
10 String text="在你来之前我们已经是冠军了";
11 
12 StringReader sr = new StringReader(text);
13 
14 IKSegmenter ik = new IKSegmenter(sr, true);
15 
16 Lexeme lex=null;
17 
18 try {
19 
20 while((lex=ik.next())!=null){
21 
22 // System.out.print(lex.getLexemeText()+"|");
23 
24 System.out.println(lex.getLexemeText());
25 
26 }
27 
28 } catch (IOException e) {
29 
30 e.printStackTrace();
31 
32 } finally {
33 
34 // 关闭流资源
35 
36 if(sr != null) {
37 
38 sr.close();
39 
40 }
41 
42 }
43 
44 }
45 
46 
47 public static void main(String[] args) {
48 
49 analysisString();
50 
51 
52 }
53 
54 }

 

 

测试结果:

加载扩展词典:ext.dic

加载扩展停止词典:stopword.dic

在你

之前

我们

已经是

冠军

上一篇:Hibernate Search索引单个租户


下一篇:java-如何在Lucene中将RAMDirectory集成到FSDirectory