您现在的位置:首页 >> 技术架构 >> 搜索引擎 >> 内容

搜索引擎基础概念

时间:2014-12-15 20:17:47

  核心提示:要先明白概念,再学习相应实现(框架)。 全文检索就如同ORM,是一个概念。ORM的框架有很多种:Hibernate、TopLink、iBatis等,我们之前学习的是Hibernate。同样的,全文检索...

   要先明白概念,再学习相应实现(框架)。
   全文检索就如同ORM,是一个概念。ORM的框架有很多种:Hibernate、TopLink、iBatis等,我们之前学习的是Hibernate。同样的,全文检索领域中也有很多种框架,Lucene就是其中的一个用开源的全文检索框架。
Lucene的主页为:http://lucene.apache.org/。有很多应用程序使用Lucene来提供全文检索的功能,如我们经常使用的Eclipse的帮助子系统,就是使用Lucene实现的。(在第一次使用的时候,会有一个进度条,那是在创建索引)。
本文档中所使用的Lucene为3.0.1的版本。以下两小节是Lucene中重要的概念。
2.全文检索的工作流程(准备知识)
如果信息检索系统在用户发出了检索请求后再去互联网上找答案,根本无法在有限的时间内返回结果。所以他要先把要检索的资源的集合放到本地(使用某种特定的结构存储),称为索引库。我们每次搜索都是在本地的索引库中进行(需要保证数据集合与索引库的一致性)。由于索引库是按照一定的结构组织的,所以查询的速度非常快。如下图:


     所以对于全文检索功能的开发,要做的有两个方面:1,维护索引库中的数据。2,在索引库中进行搜索。
对于我们的应用程序,信息集合一般就是数据库表中的记录(文章,贴子、新闻等)或文件系统中的文件等,这些资源都可以方便、简单的获取到(使用SQL查询或遍历文件夹)。对于搜索引擎,搜索范围是整个互联网中的资源,这些资源就需要专门的工具来获取了,我们把实现这个功能的软件叫做爬虫或蜘蛛,或称做网络机器人。爬虫在互联网上访问每一个网页并把把其中的内容传回本地服务器。
3.索引库结构(准备知识)
说明:以下只是用于说明倒排序索引的结构,最终的索引结构要复杂的多(要考虑更多、更复杂的情况)。还要存储关键词在文本中的编号位置(或是首字母的字符位置)等信息。
3.1.倒排序索引
   我们需要一种方法,对文档进行预处理,在文档间建立一种便于检索的数据结构,以此来提高信息检索的速度,这种数据结构就是索引。目前广泛使用的一种索引方式是倒排序索引。
倒排序索引的原理就如同查字典。要先查目录,得到数据对应的页码,在直接翻到指定的页码,而不是从第一页开始一页一页的翻,一行一行的找。对应这里,就是在索引库中除了文档外,还要生成一个词汇表(目录)。在词汇表中的每一个条记录都是“词—对应文档”的结构。记录了每一个出现过的单词,和单词出现的地方(哪些文档)。查询时先查词汇表,得到文档的编号,再直接取出相应的文档。

   把数据转成指定格式放到索引库中的操作叫做建立索引。建立索引时,在把数据存到索引库后,再更新词汇表。进行搜索时,先从检索词汇表开始,然后找到相对应的文档。如果查询中仅包含一个关键词,则在词汇表中找到该单词,并取出他对应的文档就可以了。如果查询中包含多个关键词,则需要将各个单词检索出的记录进行合并再取出相应的文档记录。
如果词汇表中有一个词“传智播客”对应的文档编号列表为“1”。现在又有添加了一个包含“传智播客”的文档,则词汇表中的“传智播客”词后对应的编号列表变成了“1,2”。因为关键词的数量受实际语言的限制,所以不用担心词汇表会变的很大。有人做过统计,对地1GB的文本信息来说,词汇表的大小在5MB左右。
3.2.索引文件的检索与维护
维护倒排索引有三个操作:插入、删除和更新文档。但是更新操作需要较高的代价。因为文档修改后(即使是很小的修改),就可能会造成文档中的很多的关键词的位置都发生了变化。这就需要频繁的读取和修改记录,这种代价是相当高的。因此,一般不进行(真正的)更新操作,而是使用“先删除,再创建”的方式代替更新操作。
    3.3.在Lucene中对索引库的操作有关知识(重点)
索引库是一堆二进制文件,有特定的结构,他们都在同一个文件夹中,这个文件夹就是索引库的位置。我们不能直接操作这些文件,因为我们不知道他的具体格式。我们也不需要直接操作他们,因为Lucene提供了操作索引库的一些工具(API),我们就是通过这些工具(API调用)对索引库做管理与搜索的操作的。如下图:

    就如同数据库,所有的数据也是以文件的形式存在文件系统中的。我们在操用数据库的时候不是直接修改这些文件,而是通过一些客户端工具,使用SQL语句来操作。这就相当于在Lucene中使用Lucene的API操作Lucene的索引库。
我们需要熟悉Lucene的相应的操作索引库的API,而对于索引库文件的结构,那是Lucene具体实现的东西的,但我们也要有所了解,以助于后面的理解。(有兴趣的同学可以多看一下有关信息检索系统的一些理论的书籍资料,这不属于我们现在要学习的范围)。
一、从我们对索引库的操作上看(通过Lucene的API):对索引库的操作,我们分为两类:索引库管理与进行搜索。
    索引库管理,使用IndexWriter。用他可以在索引库中增加、删除、更新索引数据,对应的方法为:addDocument()、deleteDocuments()、updateDocument()。也可以进行索引库的一些其他有关的修改与优化的操作,这些我们在后面的章节点再学习。
在索引库中搜索,使用IndexSearcher。对应的方法为search()。
对索引库的增删改操作,所作用的对象是一些数据(索引)。这些数据在Lucene中用一个对象来表示:Document。他里面有一个Field的集合,表示所有的属性的“键-值”对集合(一个Field代表一个属性)。我们只需要把在我们的程序中的对象转成Document,就可以交给Lucene管理了。(搜索的结果最终也是Document的集合)
二、从Lucene对索引库的操作上看。
在建立索引时,先要把文档存到索引库中,还要更新词汇表。如下图:

    文档存到索引库中后,就会自动指定一个内部编号,用来唯一标识这条数据。称之为内部编号,是因为这个编号只能在内部用。在索引库内部的数据进行调整后(一般是优化索引库时),这个编号就会改变。同时词汇表中引用的编号也会做相应改变,以保证正确。但我们如果在外面引用了这个编号,前后两次去取,得到的可能不是同一个文档!
更新词汇表时,要把哪些词放到词汇表中呢,也就是怎么从文档的文本中取出所包含的词呢?这就用到了一个叫做Analyzer(分词器)的工具。他的作用是把一段文本中的词按规则取出所包含的所有词。对应的是Analyzer类,这是一个抽象类,切分词的具体规则是由子类实现的,所以对于不同的语言(规则),要用不同的分词器。如下图:

   在进行搜索时,是先在词汇表中查找,得到符合条件的文档的内部编号的列表。再根据内部编号真正的去取出数据(Document)。如下图:

   在第1步中,需要先把查询字符串转为Lucene能接受的Query对象。这就像在Hibernate中使用HQL查询时,也要先调用Session.createQuery(hql)(返回值Query对象)转成Hibernate的Query对象一样。
在词汇表中查询之前,查询字符串也要先经过Analyzer(分词器)才可以。要求搜索时使用的Analyzer要与建立索引时使用的Analzyer要一致,才测保证测搜出正确的结果。
IndexSearcher.search()方法返回的结果中没有真正的Document数据。我们拿到的只是内部编号,所以还要再调用IndexSearcher.doc()方法取出指定内部编号对应的Document数据。这是很大的方便,我们可以只取出要显示的Document数据,在分页时要用到,因为我们不能一下就取出全部数据(一次只取一页的数据)。
4.HelloWorld
1,准备场景
2,添加Lucene环境
3,完成建立索引
4,完成在索引库中搜索

要加入的jar包有:
lucene-core-3.0.1.jar(核心包)
contrib\analyzers\common\lucene-analyzers-3.0.1.jar(分词器)
contrib\highlighter\lucene-highlighter-3.0.1.jar(高亮)
contrib\memory\lucene-memory-3.0.1.jar(高亮)

Java免费学习  Java自学网 http://www.javalearns.com

作者:不详 来源:网络
    你是从哪里知道本网站的?
  • 网友介绍的
  • 百度搜索的
  • Google搜索的
  • 其它搜索过来的
  • 网址输错了进来的
  • 太忙了不记得了
共有评论 0相关评论
发表我的评论
  • 大名:
  • 内容:
本类推荐
  • 没有
本类固顶
  • 没有
  • java学习网(www.javalearns.com) © 2014 版权所有 All Rights Reserved.
  • Email:javalearns@163.com 站长QQ:1356121699 晋ICP备14003680号-3
  • java学习网部分内容来自网络或网友发布,如侵犯了您利益,请发邮件至:javalearns@126.com,我们尽快处理!
  • Java学习网
  • 网站统计
  • 晋公网安备 14042902000001号