Lucene小结
一、全文检索概述
1.常见的全文检索
(1)window系统中的指定盘符中的某一个位置来搜索.
(2)百度或google中,可以搜索互联网中的信息,有网页,pdf,word,音频,视频等内容.
(3)在bbs系统中,有搜索文章的功能.
上边的查询功能都相似,都是查询的文本内容,查询方法也相似即找出含有指定字符串的资源,只不过是查询的范围不一样(硬盘,帮助文档,互联网).
2.全文检索的概念
(1)从大量的信息中快速、准确地找出需要的信息.
(2)搜索的内容是文本信息(不是多媒体)
(3)搜索的方式:不是根据语句的意思进行处理.
(4)全面、快速、准确是衡量全文检索系统的关键指标.
(5)概括:
* 只处理文本.
* 不处理语义.
* 搜索英文时不区分大小写.
* 结果列表有相关度排序.
3.全文检索的应用场景
常用在有大量数据出现的系统中.
* 站内搜索
(1)bbs的关键字搜索
百度贴吧等
(2)商品网站的搜索
中关村在线
(3)文件管理系统
Windows的文件搜索.
* 垂直搜索
(1)针对某个行业的搜索引擎
(2)搜索引擎的细分和延伸
(3)是针对网页库中的专门信息的整合
(4)其特点是专、深、精,并具有行业色彩
(5)可以应用于购物搜索、房产搜索、人才搜索
4.全文检索与数据库搜索的区别
(1)数据库的搜索
类似:select * from 表名 where 字段名 like '%关键字%'
缺点:
* 搜索效果比较差
* 在搜索的结果中,有大量数据被搜索出来,有很多数据是没有用的.
* 查询速度在大量数据的情况下是很难做到快速的.
(2)全文检索
* 搜索结果按相关度排序:意味着只有前几个页面对于用户来说是比较有用的,其他的结果与用户想要的答案很可能相差甚远.
数据库搜索是做不到相关度排序的.
* 因为全文检索是采用索引的方式,所以在速度上肯定比数据库方式like要快.
* 因此数据库搜索不能代替全文检索.
二、Lucene概述
1.lucene简介
* 全文检索是一个概念,而具体的实现有很多框架,lucene是其中一种.
* lucene是一个开放源代码的全文检索引擎工具包,由Apache软件基金会支持和提供.
* lucene是一个高效的,可扩展的,全文检索库.
* 全部用java实现,无需配置.
* 仅支持纯文本文件的索引(Indexing)和搜索(Search)
* 不负责由其他格式的文件抽取纯文本文件,或从网络中抓取文件的过程.
2.互联网搜索流程
* 当用户打开百度网页搜索某些数据时,不是直接找的网页,而是找百度的索引库.索引库里包含的内容有
索引号和摘要,查询出来的是摘要的内容
* 百度的索引库的索引和互联网的某一个网站相对应.
* 用户点击每一个搜索出来的内容惊醒网页查找时,这个时候找的才是互联网中的网页.
3.lucene相关细节
* 在数据库中,数据库中的数据文件存储在磁盘上,索引库也是同样,索引库中的索引数据也在磁盘上存在,我们用
Directory这个类来描述.
* 我们可以通过API来实现对索引库的增删改查的操作.
* 在数据库中,各种数据形式都可以概括为一种:表.而在索引库中,各种数据形式也可以抽象出一种数据格式:Document.
* Document的结构为:Document(List<Field>)
* Field里存放一个键值对,键值对都为字符串的形式.
* 对索引库中索引的操作实际上也就是对Document的操作.
4.lucene的索引结构
(1) 索引(Index):
* 在lucene中一个索引是放在一个文件夹中的.
* 同一个文件夹中的所有文件构成一个lucene索引.
(2)段(Segment):
* 一个索引可以包含多个段,段与段之间是独立的 ,添加新文档可以生成新的段,不同的段可以合并.
* 具有相同前缀文件的属同一个段.
* segments.gen和segments_5是段的元数据文件,也即它们保存了段的属性信息.
(3)文档(Document)
* 文档是我们建立索引的基本单位,不同的文档是保存在不同的段中的,一个段可以包含多篇文档.
* 新添加的文档是单独保存在一个新生成的段中,随着段的合并,不同的文档合并到同一个段中.
(4)域(Field):
* 一篇文档包含不同类型的信息,可以分开索引,比如标题,时间,正文,作者等,都可以保存在不同的域里.
* 不同域的索引方式可以不同.
(5)词(Term):
* 词是索引的最小单位,是经过词法分析和语言处理后的字符串.
说明:lucene的索引结构中,及保存了正向信息,也保存了反向信息.
正向信息: 按层次保存了从索引,一直到词的包含关系:
索引(Index)-->段(segment)-->文档(Document)-->域(Field)-->词(Term)
反向信息:保存了词典到倒排表的映射
词(Term)-->文档(Document)
5.简单代码示例
(1)准备开发环境
需要的jar包:
* lucene-core-3.1.0.jar (核心包)
* lucene-analyzers-3.1.0.jar (分词器)
* lucene-highlighter-3.1.0.jar (高亮器)
* lucene-memory-3.1.0.jar (高亮器)
(2)创建索引
public void testSearchIndex() throws Exception{IndexSearcher indexSearcher = new IndexSearcher(LuceneUtils.directory);QueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_30, new String[]{"title","content"}, LuceneUtils.analyzer);Query query = queryParser.parse("Lucene");TopDocs topDocs = indexSearcher.search(query, 25);ScoreDoc[] scoreDocs = topDocs.scoreDocs;/***********************************************************************///给关键字加上前缀和后缀Formatter formatter = new SimpleHTMLFormatter("<font color='red'>","</font>");//scorer封装了关键字Scorer scorer = new QueryScorer(query);Highlighter highlighter = new Highlighter(formatter,scorer);//创建一个摘要Fragmenter fragmenter = new SimpleFragmenter(10);//指定摘要大小,如果使用无参构造器,默认为100.highlighter.setTextFragmenter(fragmenter);/***********************************************************************/List<Article> articleList = new ArrayList<Article>();for(ScoreDoc scoreDoc:scoreDocs){float score = scoreDoc.score;System.out.println(score);//相关的得分Document document = indexSearcher.doc(scoreDoc.doc);Article article = DocumentUtils.document2Article(document);//使用高亮器//1、分词器:查找关键词.2、字段:在哪个字段上进行高亮.3、字段的内容:把字段的内容提取出来.String titleText = highlighter.getBestFragment(LuceneUtils.analyzer, "title", document.get("title"));String contentText = highlighter.getBestFragment(LuceneUtils.analyzer, "content", document.get("content"));if(titleText!=null){article.setTitle(titleText);}if(contentText!=null){article.setContent(contentText);}articleList.add(article);}//循环输出检索内容for(Article article:articleList){System.out.println(article.getId());System.out.println(article.getTitle());System.out.println(article.getContent());}}