读书人

Lucene总结

发布时间: 2012-12-17 09:31:40 作者: rapoo

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)文档—ocument)
* 文档是我们建立索引的基本单位,不同的文档是保存在不同的段中的,一个段可以包含多篇文档.
* 新添加的文档是单独保存在一个新生成的段中,随着段的合并,不同的文档合并到同一个段中.
(4)域(Field):
* 一篇文档包含不同类型的信息,可以分开索引,比如标题,时间,正文,作者等,都可以保存在不同的域里.
* 不同域的索引方式可以不同.
(5)词(Term):
* 词是索引的最小单位,是经过词法分析和语言处理后的字符串.
说明:lucene的索引结构中,及保存了正向信息,也保存了反向信息.
正向信息: 按层次保存了从索引,一直到词的包含关系:
索引(Index)-->段(segment)-->文档—ocument)-->域(Field)-->词(Term)
反向信息:保存了词典到倒排表的映射
词(Term)-->文档—ocument)
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());}}

8.核心API
(1)IndexWriter
* 此类可以对索引进行增、删、改操作.
* 利用构造方法可以构造一个IndexWriter的对象.
* addDocument: 向索引库中添加一个Document
* updateDocument: 更新一个Document
* deleteDocuments:删除一个Document
(2)Directory(指向索引库的位置)
* FSDirectory
①通过 FSDirectory.open(new File("./indexDir"))建立一个indexDir的文件夹,而这个文件夹就是索引库存放的位置.
②通过这种方法建立索引库时如果indexDire文件夹不存在,程序将自动创建一个,如果存在就用原来的这个.
③通过这个类可以知道所建立的索引库在磁盘上,能永久性的保存数据。这是优点.
④缺点为因为程序要访问磁盘上的数据,这个操作可能引发大量的IO操作,会降低性能.
* RAMDirectory
①通过构造函数的形式Directory ramdirectory = new RAMDirectory(fsdirectory)可以建立RAMDirectory
②这种方法建立的索引库会在内存中开辟一定的空间,通过构造函数的形式把fsdirectory移动到内存中
③这种方法索引库中的数据是暂时的,只要内存的数据消失,这个索引库就跟着消失了
④因为程序是在内存中跟索引库交互,所以利用这种方法创建的索引的好处就在效率比较高,访问速度比较快
(3)Document
* 一个Directory是由很多Document组成的。用户从客户端输入的要搜索的关键内容被服务器端包装成JavaBean,然后再转化为Document
(4)Field
* Field相当于javaBean的属性.
* new Field("title",article.getTitle(),Store.YES,Index.ANALYZED);
第一参数为属性,第二个为属性值,第三个参数为是否向索引库里存储.
第四个参数为是否更新索引库:
NO:不进行引索.
ANALYZED:进行分词引索.
NOT_ANALYZED:进行引索,把整个输入作为一个词对待.
(5)MaxFieldLength
* 能存储的最大长度.
* 在IndexWriter的构造方法里使用.
* 值:
LIMITED:限制的最大长度,值为10000
UNLIMITED:没有限制的最大长度(一般不使用)

读书人网 >互联网

热点推荐