Lucene.net 原理介绍以及使用方法


在我将要实现的仿照博客园搜索功能的简易网站中,需要用到Lucene.net进行查询,因此我整理了一下我收集的资料。
 
现实世界中包含两种类型的数据:结构化数据和非结构化数据
 
结构化数据很容易进行搜索,比如数据库包含的就是结构化数据,可以利用sql进行查询。但是对于非结构化数据,比如word、txt文件中包含的内容则属于非结构化数据。要对这些数据进行查找,只能采用顺序扫描的方式,但是顺序扫描的方式速度很慢。

但是在Lucene的世界中,把所有数据都作为字符串来处理,通过Lucene来进行查找,通常会分成两步,一步就是创建索引,另一步就是查找索引。

因为创建好的索引属于结构化数据,所以可以很快的进行查找。并且Lucene创建索引的方式采用的倒排索引的存储。

 

每个字符串都指向包含此字符串的文档(Document)链表,称谓倒排表。采用倒排表进行存储的索引结构就称为倒排索引。
 

也许有人会说,创建索引的时间会非常长,加上搜索索引的时间不一定会比直接采用顺序查找的速度要快。这个看法我是很赞同的,我就曾经采用Lucene创建索引,索引一篇word书籍,整整索引了八个小时才完成。我想如果我打开word直接查找也就是几分钟的事情。但是我为什么非要建立索引不可呢?原因也很简单,就是顺序扫描每次搜索都会重新执行一次,但是索引只需要索引一次,以后就都可以使用。这也就是创建索引的根本目的:一次索引,多次使用。

在搜索的过程中,我们往往是想让相关度较高的排在前面,这就会用到权重的概念。


找出词(Term)对文档重要性的过程称为计算词的权重(Weight)的过程。搜索出来的文档应该是按照权重的顺序进行排列,按从小到大的次序。

计算词的权重会关系到两个参数,一个是词(Term),另一个是文档(Document).

词的权重表示的是此词在此文档中的重要程度,越重要的词有越大的权重,因而在计算文档之间的相关性中将发挥更大的作用。

 

Lucene搜索过程通常分为三步:创建、索引、搜索

  • 被索引的文档用Document对象表示
  • IndexWriter通过函数adDocument将文档添加到索引中,实现创建索引的过程
  • Lucene的索引采用的反向索引。对应我前面说的反向链表
  • 当用户有请求时,Query代表用户的查询语句。
  • IndexSearcher通过函数search搜索    Lucene Index
  • IndexSearcher计算term weight和score并且将结果返回给用户。再返回给用户数据之前,Lucene还会按照权重进行排序
  • 返回给用户的文档集合用TopDocsCollector表示

Lucene中的基本概念:Term (词) Document(文档) Field(字段(和数据库字段类似)) Query(查询) QueryParser(查询解析器) IndexWriter(负责生成索引并存储)

IndexReader(读取硬盘中的索引文件并存入内存) Hits(命中 我也不能很好的翻译这个词的意思 就是返回搜索的数据)


Lucene。net的基本使用方法


1 public void CreateIndex()//创建索引 2 { 3 Document doc = new Document(); 4 doc.Add(new Field("name", "我是郭志奇", Field.Store.YES, Field.Index.NOT_ANALYZED)); 5 doc.Add(new Field("val", "", Field.Store.YES, Field.Index.ANALYZED)); 6 IndexWriter writer = new IndexWriter(FSDirectory.Open(new DirectoryInfo("")), new Standard Analyzer(), true, IndexWriter.MaxFieldLength.LIMITED); 7 writer.AddDocument(doc); 8 writer.Optimize(); 9 writer.Close(); 10 } 11 12 13 public void Search(string queryString, int num)//搜索 14 { 15 IndexReader reader = IndexReader.Open("", true); 16 IndexSearcher searcher = new IndexSearcher(reader); 17 //创建查询 18 Analyzer analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29); 19 QueryParser parser = new QueryParser("", analyzer); 20 Query query = parser.Parse(queryString); 21 TopScoreDocCollector collector = TopScoreDocCollector.create(num, true); 22 Hits hits = searcher.Search(query); 23 //以后就可以对获取到的collector数据进行操作 24 for (int i = 0; i < hits.Length(); i++) 25 { 26 Document doc = hits.Doc(i); 27 Field keyFieldVal = doc.GetField("key"); 28 string strKey = keyFieldVal.StringValue();//获取到Field 键值key的值 29 } 30 } 31 public void DeleteIndex()//删除索引 32 { 33 34 IndexWriter writer = new IndexWriter(FSDirectory.Open(new DirectoryInfo("")), new Standard Analyzer(), true, IndexWriter.MaxFieldLength.LIMITED); 35 writer.DeleteAll();//删除所有的索引 36 writer.DeleteDocuments(new Term("key", "val"));//删除该词条 37 //注意 在执行这个删除操作的时候,其实lucene本身并没有将数据从硬盘删除,而是保存到了一个单独的后缀名为.del的文件中。 38 writer.Commit();//进行提交操作 标记为删除的索引会被从硬盘删除 39 40 }


Lucene可以进行的操作方法有很多,分词器也有很多,但是Lucene.net自带的分词器不能很好的支持中文,因此对于有中文的搜索我推荐盘古分词,很好很强大。
还有一点用惯.net的朋友使用Lucene.net的时候会觉得不习惯,因为在.net中是属性的东西,在Lucene.net中是用方法表示的,因为据我所知,在Java中是不存在和.net中的属性一说的。

索引:
Asp.net MVC 使用Autofac的简单使用 IOC (2012-12-12 13:16)   8 649 547    
Asp.net MVC 仿照博客园的简单网站首页 列表设计 (2012-12-11 22:21) 发布 12 928 277    
为什么要从Web form过渡到MVC中 (2012-12-09 22:43) 发布 88 5253 478    
Asp.net MVC3 企业网站系统高仿博客园 首页左侧列表页面 实现效果 (2012-12-08 19:11) 发布 41 2506 361    
Asp.net MVC 3 开发企业网站系统仿照博客园部分功能--总体设计 (2012-12-05 23:41) 发布 36 2064 515    
Asp.net MVC 3 开发简单的企业系统开篇--数据库 (2012-12-03 21:03) 发布 43 3016 351    
Asp.net MVC 3 开发一个简单的企业网站系统 (2012-12-02 21:09)

 

posted @ 2012-12-13 23:49  baidixing  阅读(7926)  评论(15编辑  收藏  举报