架构深渊

慢慢走进程序的深渊……关注领域驱动设计、测试驱动开发、设计模式、企业应用架构模式……积累技术细节,以设计架构为宗。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

LUCENE.NET学习总结一

Posted on 2008-11-24 15:47  chen eric  阅读(317)  评论(0编辑  收藏  举报
2008年02月22日 星期五 下午 09:04
Lucene是有名的开源搜索框架,具体细节自己查。对于英文来说,其对分词的处理已经比较不错,但是对于日文,中文等的处理太差,所以对我们中文来说,分词是瓶颈。因为不是按照间隔区分“词汇”的,我才接触,到项目中,使用,已经是快一年了,因为自己很喜欢c#,所以,一直就关注的是LUCENE.NET,没有时间看lucene(java)版本的。当然,我的java水平真的拿不出来让大家一笑。
   
   我先通俗的介绍一些其保存数据的方式,它把数据按照其一个索引值保留,搜索的时候直接对其索引位置获取,再由这个值取具体的值。
  
   下面我说使用,和常见的DB操作一样,需要了解的是:新建,删除,编辑更新(先删除,再更新),合并,优化。
  
   我下面有时间的话会详细的介绍其使用,由于开源,我就把关键代码贴出来就可以了。

  1:创建索引
   首先创建一个目录,保持所有文件的。
//private Directory directory =new RAMDirectory(FSDirectory.GetDirectory(@TUtility.StaticIODataPath, true));
//private Directory directory =new RAMDirectory(@TUtility.StaticIODataPath);
private Directory directory =FSDirectory.GetDirectory(@TUtility.StaticIODataPath.TrimEnd('/')+"/"+"wordtype", false);//第一次True,以后false
  
注释说明:
   RAMDirectory(缓存)和 FSDirectory都可以使用(注意 FSDirectory.GetDirectory 的 create 参数,为 true 时将删除已有索引库文件,如果需要,则可通过 IndexReader.IndexExists() 方法判断)

从指定目录打开已有索引库。
private Directory directory = FSDirectory.GetDirectory("c:\index", false);

将索引库载入内存,以提高搜索速度。
private Directory directory = new RAMDirectory(FSDirectory.GetDirectory(@"c:\index", false));
//或
//private Directory directory = new RAMDirectory(c:\index");


   第二步骤就是创建一个分析器,就是来分词的,中文分词的有雨痕的,shooot的,SharpICTCLAS等等,还有个JB 海量的,主要依靠的是庞大的分词库,这个在以后的慢慢岁月有时间的话我慢慢说:

private Analyzer analyzer = new StandardAnalyzer();

我这是标准的分词,Lucene自带的
  
然后就是创建一个IndexWriter ,和XmlWriter一样,往下面写:
      IndexWriter writer = new IndexWriter(ufile, analyzer, true);//第一次True,以后false
     //writer.SetMaxFieldLength(1000);
     writer.SetMaxMergeDocs(2);//文档合并数
     //writer.SetMergeFactor(1000);//合并因子
     writer.AddDocument(GetNewDocument(new string[]{initvalue,initvalue}));
     writer.Optimize();
     writer.Close();//保存
     writer.SetUseCompoundFile(true);//合并文件

GetNewDocument是我自己定义的,原型如下:

private Document GetNewDocument(string[] args){
     Document document = new Document();
     document.Add(new Field("HashKey",         args[0],             Field.Store.YES, Field.Index.UN_TOKENIZED));
     document.Add(new Field("ChineseName",     args[1],             Field.Store.YES, Field.Index.UN_TOKENIZED));
     return document;
}


主要是创建一个Term,是索引的最小因子,记录的就是这个对象了。

其中,需要说明的是,IndexWrite.AddDocument这个方法不检测重复值,如果你需要更新的话,就先找出原来已经存在的(系列教程会说的),删除,然后添加。

IndexWriter的第三个参数是当你判断segments文件存在不,true意味着新建库或覆盖已经存在的库,false意味着追加到已经存在的库,如果false但是没有segment和cfs文件,那就报错,所以之前的,判断是不是第一次,就重要了:

if(!IndexReader.IndexExists(directory)){
//第一次,需要初始化
//MakeInit(directory);
}
  


,创建索引文件差不多就到这里吧,具体细节可以复制具体的类或者方法名,自己查。

以后我慢慢的吧所有的体会都写出来。再做和demo!伟大的计划啊.