您的位置:首页 > 其它

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

2012-12-13 23:49 656 查看

在我将要实现的仿照博客园搜索功能的简易网站中,需要用到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)8649547
Asp.net MVC 仿照博客园的简单网站首页 列表设计 (2012-12-11 22:21)发布12928277
为什么要从Web form过渡到MVC中 (2012-12-09 22:43)发布885253478
Asp.net MVC3 企业网站系统高仿博客园 首页左侧列表页面 实现效果 (2012-12-08 19:11)发布412506361
Asp.net MVC 3 开发企业网站系统仿照博客园部分功能--总体设计 (2012-12-05 23:41)发布362064515
Asp.net MVC 3 开发简单的企业系统开篇--数据库 (2012-12-03 21:03)发布433016351
Asp.net MVC 3 开发一个简单的企业网站系统 (2012-12-02 21:09)

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: