技术介绍一款全文搜索引擎--lucene

Posted BitTiger

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了技术介绍一款全文搜索引擎--lucene相关的知识,希望对你有一定的参考价值。

今天我想给大家介绍的,是一款叫做lucene的开源搜索引擎。它是基于java环境下的,一款全文搜索引擎。如果你需要对非常多的文档进行搜索,可以考虑使用它。

   
lucene进行搜索
【技术】介绍一款全文搜索引擎--lucene

1
通过对目标文档的处理,得到一个新的处理好的index。

这些index是长成这个样子的:

【技术】介绍一款全文搜索引擎--lucene
在这里,lucene 所做的事情其实是把这些文档中的话先进行预处理。比如lucene会把"BitTiger" 转换成"bitgtiger" 也就是全部小写化。之后呢,lucene 会为你的文档建立一个matrix。这里我直接开始举例说明。

doc1 : "I love programming";
doc2: "programming is necessary skills and you should love it "

lucene 会建立如下的索引结构:

term           docs        location




I                     1               1.0  


love                  1,2           1.2->2.47

programming          1,2           1.7->2.00

skills                2               2.26

and                   2               ---

you                   2               ---

it                    2               ---

is                    2               ---


term 代表出现在文档中的一个一个词语,docs代表的是这个文档的编号,lcoation代表的是词语出现在文档中的某个位置。在lucene当中,词语的位置是用一个linkedlist 串联起来的。

如果你要对一段文档进行索引,在API,你要做的事情很简单,我在这里直接贴代码
String path = "XXXXX"; ----------- 你文档的路径
final Path docDirs = Paths.get(Path);
// 你建立索引的路径
Directory dic_siwei = FSDirectory.open(Paths.get("你建立一个大索引的路径"));
Analyzer analyzer = new StandardAnalyzer();  ------ 构建分析器,它的作用是对文档语言进行处理
//配置索引writer和建立一个索引
IndexWriterConfig conf = new IndexWriterConfig(analyzer);
IndexWriter writer = new IndexWriter(dic_siwei,conf);
Document docs = new Document();
这里docDir是单独一个文件的路径,我省略了之前的一个方法,大家知道就行
InputStream stream = Files.newInputStream(docDir);
doc.add(new TextField("contents", new BufferedReader(newInputStreamReader(stream, StandardCharsets.UTF_8))));
writer.close();

这之后,你们就可以创建好一份索引。在这里你会问,如果我的添加了一个新的索引,那么我需不需要重新跑一次我的程序,去建立一个新的索引。在这里,lucene处理的很好。当你有新的文件需要进行处理,lucene提供了一个"updata" 接口可以将你的新内容加入到原来的索引文件中。

2
建立好索引之后如何进行搜索?

我觉得在这里,我想谈谈lucene的打分机制。比如我搜索“dota ti5”,我希望第一个搜索的结果文档叫做"dota2"而不是“英雄联盟(LOL)”.那么lucene是如何做的呢?
lucene 默认的搜索算法叫做TF/IDF 算法。

2.1(TF/IDF 算法)

TF-IDF算法全称为term frequency–inverse document frequency。TF就是term frequency的缩写,意为词频。IDF则是inverse document frequency的缩写,意为逆文档频率。
该算法在信息处理中通常用来抽取关键词。比如,对一个文章提取关键词作为搜索词,就可以采用TF-IDF算法。
要找出一篇文章中的关键词,通常的思路就是,就是找到出现次数最多的词。如果某个词很重要,它应该在这篇文章中多次出现。于是,我们进行"词频"(Term Frequency,缩写为TF)统计。
但是通常,一篇中文的文章中,都会有很多没有实际意义的词,比如“的”,“是”,“了”,这类词是最常用的词,称为停用词,称它们为停用词是因为在文本处理过程中如果遇到它们,则立即停止处理,将其扔掉。将这些词扔掉减少了索引量,增加了检索效率,并且通常都会提高检索的效果。停用词主要包括英文字符、数字、数学字符、标点符号及使用频率特高的单汉字等。
当过滤掉所有的停用词后,剩下的都是实际意义的词,但也不能简单的认为那个词出现的次数多就是关键词。比如在一篇如何组装电脑的文章中,出现“CPU”,“主板”等关键词和出现“说明书”的次数一样多,但很显然,CPU,主板等关键词,更能确定这个文章的特性。也就是说,“CPU”,“主板”等关键词比“说明书”这个关键词更重要,需要排在前面。所以我们就需要一个权重系数,用来调整各个关键词的重要性。如果一个词很少见,但是它在某个文章中反复出现多次,那么可以认为这个词反应了这个文章的特性,可以把它作为关键词。在信息检索中,这个权重非常重要,它决定了关键词的重要度,这个权重叫做"逆文档频率"(Inverse Document Frequency,缩写为IDF),它的大小与一个词的常见程度成反比。
在知道了词频和权重之后,两者相乘,就得到一个词的TF-IDF值,某个词对文章的重要性越高,它的TF-IDF值就越大。所以,排在最前面的几个词,就是这篇文章的关键词。
因此TF-IDF算法的主要工作就是计算出TF*IDF值最大的那几个词,作为文章的关键词。

可是,TF-IDF算法的优点是简单快速,结果比较符合实际情况。缺点是,单纯以"词频"衡量一个词的重要性,不够全面,有时重要的词可能出现次数并不多。而且,这种算法无法体现词的位置信息,出现位置靠前的词与出现位置靠后的词,都被视为重要性相同,这是不正确的。(一种解决方法是,对全文的第一段和每一段的第一句话,给予较大的权重。)
当通过TF-IDF算法找出文章的关键字后,可以运用到一些具体的场景。比如:根据关键字找出相似的文章。

2.2 代码怎么写?

//配置搜索器
IndexReader reade=DirectoryReader.open(FSDirectory.open(Paths.get(“你刚才建立索引的文件夹”)));
IndexSearcher searcher = new IndexSearcher(reader);

Analyzer analyzer = new StandardAnalyzer();
QueryParser parser = new QueryParser(field, analyzer);
Query query = parser.parse("你要搜索的内容");
// topDocs 就是就是你要得到的10个评分最高的文档
TopDocs results = searcher.search(query, 10);

2.3 其他算法扩展

如果你认为lucene本身的算法不够好,那么你可以考虑去实现其他的算法。比如BM25和BM25F算法。在lucene当中,如果你想更改原本的算法,那么你需要extends原来的Similarity类,然后将它配置到你的索引writer的配置中。如果你需要更好的索引。那么你可能需要为lucene重写很多代码,包括权重包(Weight),Query包(查询),Score包(打分)。

3
小小的展望

这是博主第一次写博客,真的第一次都献给了BitTiger啊有木有!博主表示如果文章写的不好,请见谅啊!

小组简介:亚特兰大地区小组Ranger,我们四个人都是CS相关专业的学生,三位GT一位Emory的。这里诚招一位兼职技术顾问,学生党经验不足啊!
太阁实验室
有趣,有用,有效;
刷项目,做实战,捅破技术那层纸
论码农的自我修养
WeChat ID: bit_tiger
长按二维码,关注我哟~
猛戳这里查看原文
↓↓↓ 

以上是关于技术介绍一款全文搜索引擎--lucene的主要内容,如果未能解决你的问题,请参考以下文章

全文检索技术---Lucene

全文搜索引擎 Elasticsearch 介绍

分布式--Lucene 全文检索

Solr全文检索基本原理及评分机制

原创Lucene001--介绍和入门

全文检索——Lucene