全文搜索Lucene——之倒排算法

标签: 搜索 lucene 算法 | 发表时间:2014-12-10 17:05 | 作者:673181695
出处:http://www.iteye.com
背景

  关系数据库不适合做全文搜索
  • like '%xxx%'效率很慢,建的索引将无效,查询的时候会像翻书一样一页一页的翻
  • 返回的结果没有匹配度的概念,比如在所有文章里索引一篇想要的文章,可能是希望搜索的关键词在文章中出现的次数越多越是我想要的结果
  • 当搜索live的时候,也想把lives/living搜出来,但是数据库很难做到
倒排算法
   了解倒排算法之后方便理解为什么搜索引擎非常适合做全文搜索。简单来说倒排算法就是通过关键词快速定位到文章,首先记录了很多的关键词,关键词里记录了该关键词在哪些文章里出现了,当用户搜索的时候先找到关键词,然后计算出最相关的头几十篇文章返回给用户。
    Lucene在国外知名度很高,现在已经是Apache的顶级项目,国内也有很多应用,它使用的就是倒排文件索引结构,算法结构如下:
(0)设有两篇文章1和2
   文章1的内容为:Tom lives in Guangzhou,I live in Guangzhou too
   文章2的内容为:He once lived in Shanghai.
(1)全文分析:由于lucene是基于关键词索引和查询的,首先我们要取得这两篇文章的关键词,通常我们需要如下处理措施
        
  • a.我们现在有的是文章内容,即一个字符串,我们先要找出字符串中的所有单词,即分词。英文单词由于用空格分隔,比较好处理。中文单词间是连在一起的需要特殊的分词处理。
  • b.文章中的”in”, “once” “too”等词没有什么实际意义,中文中的“的”“是”等字通常也无具体含义,这些不代表概念的词可以过滤掉
  • c.用户通常希望查“He”时能把含“he”,“HE”的文章也找出来,所以所有单词需要统一大小写。
  • d.用户通常希望查“live”时能把含“lives”,“lived”的文章也找出来,所以需要把“lives”,“lived”还原成“live”
  • e.文章中的标点符号通常不表示某种概念,也可以过滤掉

    经过上面处理后
  文章1的所有关键词为:[tom] [live] [guangzhou] [i] [live] [guangzhou]
  文章2的所有关键词为:[he] [live] [shanghai]
(2) 倒排索引:有了关键词后,我们就可以建立倒排索引了。上面的对应关系是:“文章号”对“文章中所有关键词”。倒排索引把这个关系倒过来,变成:“关键词”对“拥有该关键词的所有文章号”。文章1,2经过倒排后变成
关键词   文章号
  guangzhou 1
  he       2
  i         1
  live      1,2
  shanghai  2
  tom       1

(3)通常仅知道关键词在哪些文章中出现还不够,我们还需要知道关键词在文章中出现次数和出现的位置,通常有两种位置:a)字符位置,即记录该词是文章中第几个字符(优点是关键词亮显时定位快);b)关键词位置,即记录该词是文章中第几个关键词(优点是节约索引空间、词组(phase)查询快),lucene中记录的就是这种位置。
加上“出现频率”和“出现位置”信息后,我们的索引结构变为:
 关键词  文章号  [出现频率]  出现位置
 guangzhou  1  [2]  3,6
 he  2  [1]  1
 i  1  [1]  4
 live  1  [2]  2,5
   2  [1]  2
 shanghai  2  [1]  3
 tom  1  [1]  1

(4)  以live 这行为例我们说明一下该结构:live在文章1中出现了2次,文章2中出现了一次,它的出现位置为“2,5,2”这表示什么呢?我们需要结合文章号和出现频率来分析,文章1中出现了2次,那么“2,5”就表示live在文章1中出现的两个位置,文章2中出现了一次,剩下的“2”就表示live是文章2中第 2个关键字。
  以上就是lucene索引结构中最核心的部分。我们注意到关键字是按字符顺序排列的(lucene没有使用B树结构),因此lucene可以用二元搜索算法快速定位关键词。
结语
参考:http://www.chedong.com/tech/lucene.html
参考的这篇文章里讲得更详细,网上也有很多介绍倒排算法的文章。既然已经有了,为什么我还要写这篇文章呢?我的考虑是倒排算法是搜索引擎的核心,理解了它能更好的理解搜索引擎的其他东西,也作为后续关于搜索引擎文章的完整性。


已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [搜索 lucene 算法] 推荐:

全文搜索Lucene——之倒排算法

- - 互联网 - ITeye博客
  关系数据库不适合做全文搜索. like '%xxx%'效率很慢,建的索引将无效,查询的时候会像翻书一样一页一页的翻. 返回的结果没有匹配度的概念,比如在所有文章里索引一篇想要的文章,可能是希望搜索的关键词在文章中出现的次数越多越是我想要的结果. 当搜索live的时候,也想把lives/living搜出来,但是数据库很难做到.

[原]Lucene系列-近实时搜索

- - 文武天下
近实时搜索(near-real-time)可以搜索IndexWriter还未commit的内容,介于immediate和eventual之间,在数据比较大、更新较频繁的情况下使用. lucene的nrt可以控制更新生效的间隔时间. 从indexwriter中获得indexreader. 建立indexsearcher.

lucene-对多个索引的搜索和多线程搜索

- - 编程语言 - ITeye博客
1、如果应用程序架构由多个LUCENE索引组成,则可以通过MutltiSearcher把所有索引搜索. 也可以通过ParallelMultiSearcher进行多线程搜索. 在单核的情况下,MultiSearcher比ParallelMultiSearcher性能更高. 搜索2个搜索,把动物按首字母在字母表中的位置分成2部分,一部分一个索引.

LIRE(Lucene Image Retrieval)相似图像索引和搜索机制

- - CSDN博客云计算推荐文章
众说周知,lucene是一个开源的强大的索引工具,但是它仅限于文本索引. 基于内容的图像检索(CBIR)要求我们利用图像的一些基本特征(如颜色纹理形状以及sift,surf等等)搜索相似的图片,LIRE(Lucene Image Retrieval)是一款基于lucene的图像特征索引工具,它能帮助我们方便的对图像特征建立索引和搜索,作者也在不断加入新的特征供用户使用.

开源搜索引擎评估:lucene sphinx elasticsearch

- - 鲁塔弗的博客
lucene系,java开发,包括 solr和 elasticsearch. sphinx,c++开发,简单高性能. 搜索引擎程序这个名称不妥当,严格说来应该叫做 索引程序(indexing program),早期主要用来做中文全文搜索,但是随着互联网的深入普及,各家网站规模越来越大,索引程序在 优化网站架构上发挥了更大的作用: 替代mysql数据库 内置的索引.

[原]基于Lucene多索引进行索引和搜索

- - 千与的专栏
Lucene支持创建多个索引目录,同时存储多个索引. 我们可能担心的问题是,在索引的过程中,分散地存储到多个索引目录中,是否在搜索时能够得到全局的相关度计算得分,其实Lucene的ParallelMultiSearcher和MultiSearcher支持全局得分的计算,也就是说,虽然索引分布在多个索引目录中,在搜索的时候还会将全部的索引数据聚合在一起进行查询匹配和得分计算.

lucene排序

- - 开源软件 - ITeye博客
排序是对于全文检索来言是一个必不可少的功能,在实际运用中,排序功能能在某些时候给我们带来很大的方便,比如在淘宝,京东等一些电商网站我们可能通过排序来快速找到价格最便宜的商品,或者通过排序来找到评论数最高或卖的最好的商品,再比如在Iteye里的博客栏里,每天都会以降序的方式,来显示出最新发出的几篇博客,有了排序,我们就能在某些时候很方便快速的得到某些有效信息,所以说排序功能,无处不在 ^_^.

分布式搜索算法

- - 杨尚川的个人页面
对于搜索引擎来说,索引存放在成千上万台机器上,如何进行分布式搜索呢. 假设搜索结果是以分页的方式显示,以PageNumber代表当前页,从1开始,以PageSize代表页面大小,默认为10,以N代表搜索服务器数量. 最简单的分布式搜索算法为:有一台 合并服务器负责接受用户的搜索请求,然后分别向N台机器获取前PageNumber*PageSize条结果,得到的结果数为N*PageNumber*PageSize,然后把这些数据重新进行排序,根据所要显示的页面PageNumber,获取从(PageNumber - 1) * PageSize + 1开始的PageSize条结果返回给用户.

[原]Lucene系列-facet

- - 文武天下
facet:面、切面、方面. 个人理解就是维度,在满足query的前提下,观察结果在各维度上的分布(一个维度下各子类的数目). 如jd上搜“手机”,得到4009个商品. 其中品牌、网络、价格就是商品的维度(facet),点击某个品牌或者网络,获取更细分的结果. 点击品牌小米,获得小米手机的结果,显示27个.

[原]Lucene系列-FieldCache

- - 文武天下
域缓存,加载所有文档中某个特定域的值到内存,便于随机存取该域值. 当用户需要访问各文档中某个域的值时,IndexSearcher.doc(docId)获得Document的所有域值,但访问速度比较慢,而且只能获得Stored域的值. FieldCache能获得域值数组,根据docId random access域值.