Lucene

维基教科书,自由的教学读本

简介[编辑]

Lucene最初是由Doug Cutting所撰写的,是一位资深全文索引/检索专家,曾经是V-Twin搜索引擎的主要开发者,后来在Excite担任高级系统架构设计师,目前从事于一些INTERNET底层架构的研究。他贡献出Lucene的目标是为各种中小型应用程序加入全文检索功能。 Lucene提供了一个简单却强大的应用程序界面,能够做全文索引和搜寻,在java里Lucene是一个成熟的免费开放源代码工具;就其本身而论,Lucene是现在并且是这几年,最受欢迎的免费java资讯检索程式库。人们经常提到资讯检索程式库,就像是搜索引擎,但是不应该将资讯检索程式库与网搜索引擎相混淆。

如何使用Lucene[编辑]

Step1:Lucene下载完后将里面的lucene-core-{version}.jar 和lucene-demos-{version}.jar 和 queryparser/lucene-queryparser-{version}.jar 放到

     C:\Program Files\Java\jdk1.5.0_11\jre\lib\ext的目錄下

Step2:将上面的3个.jar的档案路径加入到CLASSPATH里完成上面步骤后就可以在Command line下使用Lucene建立Index以及Search。

建立Index:
在Command line下输入java org.apache.lucene.demo.IndexFiles {full-path-to-lucene}/src 即可建立Index。

Search:
在建立完Index之后接着输入java org.apache.lucene.demo.SearchFiles之后会出现Query:字样接着就可以开始Search。

linux环境, lucene-6.3.0例子:

  1. 取得 lucene-6.3.0.tgz。
  2. 假设id为boy, cd /home/boy;mkdir lucene
  3. cd /home/boy; tar zxf lucene-6.3.0.tgz
  4. export CLASSPATH=/home/boy/lucene-6.3.0/core/lucene-core-6.3.0.jar:/home/boy/lucene-6.3.0/demo/lucene-demo-6.3.0.jar:/home/boy/lucene-6.3.0/queryparser/lucene-queryparser-6.3.0.jar
  5. cd /home/boy;java org.apache.lucene.demo.IndexFiles -docs /home/boy/lucene-6.3.0 将会读取/home/boy/lucene-6.3.0档案,建立index在目录 /home/boy/index。
  6. java org.apache.lucene.demo.SearchFiles之后会出现Query:字样接着就可以开始Search。

Lucene分词原理[编辑]

假若有以下2篇文章:

文章1的内容是:Tom lives in Guangzhou,I live in Guangzhou too.

文章2的内容是:He once lived in Shanghai.

Lucene是用关键词索引和搜寻的,所以我们要先取得上面两篇文章的关键词,步骤如下:

Step1:先找出文章中所有的单字,即分词,因为英文单字是用空格分隔,所以比较好处理,若是中文分词需用到特殊的分词处理。

Step2:把文章中没有意义的单字滤掉,EX:"in","once","too"等等,在中文中就是,"的","是"等等。

Step3:使用者若查询"He"时要能把"he","HE"的文章也找出来,所以所有单字需要统一大小写。

Step4:使用者若查询"live"时,也要将"lives","lived"的文章找出来所以需要把"lives","lived"还原成"live"。

Step5:文章中的标点符号也可以过滤掉。

以上步骤在Lucene中是由Analyzer来完成的。

文章经过处理后:

文章1的所有关键词为:[tom] [live] [guangzhou] [i] [live] [guangzhou]

文章2的所有关键词为:[he] [live] [shanghai]

有了所有的关键词后,我们就可以开始建立倒排索引了。

上面处理过的文章所对应的关系是:"文章编号","文章中所有的关键词"。

若使用一般的索引结构会如下表所示:

文章编号 出现的关键词 出现次数
1 guangzhou,i,live,tom 1,1,1,1
2 he,live,shanghai 1,1,1

从中可以看出一般索引结构是以文章为标准建立索引结构,也就是说他纪录的是一篇文章中所有的关键词出现的情况,EX:文章2中he,live,shanghai均出现一次,然而使用者进行搜寻时,都是输入关键字进行搜寻,若用这种索引结构,在查某依关键字时往往需要遍及所有的索引,当索引量非常大时,效率会成为一个很大的问题。

而倒排索引会把这关系变成:"关键词","出现关键词的所有文章编号"。

所以索引结构如下表所示:

关键词 出现关键词的所有文章编号
guangzhou 1
he 2
i 1
live 1,2
shanghai 2
tom 1

通常只知道以上资讯是不够的,我们还需要知道关键词在文章中出现的次数以及位置。

关键词位置有两种:

符号位置:即纪录该关键词是在文章中第几个符号。

关键词位置:即记录该关键词是在文章中的第几个关键词。(Lucene所用的)

所以上面的资料加入"出现频率"和"出现位置"的讯息后,索引结构就如下表所示:

关键词 出现关键词的所有文章编号[出现频率] 出现位置
guangzhou 1[2] 3,6
he 2[1] 1
i 1[1] 4
live 1[2],2[1] 2,5,2
shanghai 2[1] 3
tom 1[1] 1

以live这行来说明索引结构:live在文章1中出现了2次,在文章2中出现了1次,出现的位置为"2,5,2",也就是说live在文章1中出现了2次,位置分别是"2,5";live在文章2中出现了一次,位置是"2"。

上面就是Lucene索引结构中最核心的部分。我们可以看出关键词是依照符号顺序排列的,因此Lucene可以利用二元搜寻法来定位关键词。

实际上Lucene将上面的"关键词","文章编号[出现频率]","出现位置"分成(辞典文件)Term Dictionary,(频率文件)frequencies,(位置文件)positions保存。

其中Term Dictionary不只存有每个关键词,还保留了frequencies和positions的指针,透过指针可以找到该关键词的频率讯息和位置讯息。

Lucene也使用了field的概念,field是用于表达讯息的所在位置(EX:标题中,文章中,url中),在建立索引时field的讯息也被记录在Term Dictionary中,每一个关键词都有一个field讯息(因为每一个关键词一定属于一个或多个)。

下面我们将说明为什么要建立索引(Index):

假设我们查询"live",Lucene会用二元搜寻法对Term Dictionary做关键词的寻找,找到该关键词后,透过指向frequencies的指针读出所有的文章编号,然后将找到的文章输出给使用者。Term Dictionary通常都很小,所以整个过程的时间是毫秒级的。

外部链接[编辑]