【蛙蛙推荐】Lucene.net试用

【简介】
  lucene.net好多人都知道的吧,反正我是最近才好好的看了一下,别笑我拿历史当新闻哦,不太了解Lucence的朋友先听我说两句哦。Lucene的知识主要分为索引、搜索、分析器、性能优化几个部分。索引和搜索没啥可说的,看几个例子就会了,来回那一套儿,按部就班做几个实验就熟悉了。分析器是Lucence的精华,又分为分词和过滤两部分,而且中文分词更是难点,我的例子里是用从博客园程序中提取出来的Lucene.Net.Analysis.Cn.dll来实现中文分词的,谁有中科院的那套中科院ICTCLAS分词工具的C#版麻烦提供一下哦。性能优化也很重要,因为如果要索引的文件比较大的话,建立索引的性能就会很大的下降,你可以调整IndexWriter的几个参数来优化索引性能,还有可以用IndexWriter.Optimize()方法(这个方法主要是优化查询速度,反而使索引性能有所下降),另外就是可以用多线程来分别对不同的内容进行索引并保存到RAMDirectory里,然后再把所有的内存索引合并到FSDirectory里,甚至可以让多台服务器分别处理内容的各个部分,然后把索引结果放到一个队列里,再有一台机器去读取索引结果队列并合并索引结果。
  做这个示例主要是为了演示一下Lucene.net的功能,它可以对你指定的目录里的.txt,.htm,.html文件进行全文索引,然后对其进行查询。由于如果要索引的目录里文件特别多特别大的话,建立索引需要花费很长的过程,所以我在示例程序里使用了异步编程,以便在建立索引的时候不阻塞界面线程。
【内容】
1、先看一个简单例子
public void Test1()
{
 //建立一个内存目录
 Lucene.Net.Store.RAMDirectory ramDir = new Lucene.Net.Store.RAMDirectory();

 //建立一个索引书写器
 IndexWriter ramWriter = new IndexWriter(ramDir,new ChineseAnalyzer(), true);

 //要索引的词,这就相当于一个个的要索引的文件
 string[] words = {"中华人民共和国", "人民共和国", "人民","共和国"}; 

 //循环数组,创建文档,给文档添加字段,并把文档添加到索引书写器里
 Document doc = null; 
 for (int i = 0; i < words.Length; i++)
 {
  doc = new Document();
  doc.Add(Field.Text("contents", words[i]));
  ramWriter.AddDocument(doc);
 }

 //索引优化
 ramWriter.Optimize();

 //关闭索引读写器,一定要关哦,按理说应该把上面的代码用try括主,在finally里关闭索引书写器
 ramWriter.Close();

 //构建一个索引搜索器
 IndexSearcher searcher = new IndexSearcher(ramDir);

 //用QueryParser.Parse方法实例化一个查询
 Query query = QueryParser.Parse("中华人民","contents",new ChineseAnalyzer());

 //获取搜索结果
 Hits hits = searcher.Search(query);

 //判断是否有搜索到的结果,当然你也可以遍历结果集并输出
 if (hits.Length() != 0)
  MessageBox.Show("有");
 else
  MessageBox.Show("没有");
}
2、其它的具体看下载代码吧。
  下载的文件里有个doc的文件夹,里面有4个文本文件,大家可以试着给那个目录建立索引,然后搜索一下“人民”,“中华”等几个关键字,看看能出来搜索结果吗?简单说一下示例程序,就是遍历一个目录,找出所有文本和网页的文件,建立Lucene的Document文件,并索引了文件的目录和内容,然后添加到索引器里,最后在程序执行目录的Index子目录里建立索引,这一部分的调用使用了异步委托。搜索的时候就是在Index目录里检索符合某个关键字的条目。
【注意】
1、建立完索引后一定要调用IndexWriter的Close方法,否则如果你要索引的目录里的文件少于minMergeDocs的话,是不能建立索引的。
2、Field.Text的静态方法有两个重载版本,如果第二个参数是string的话那么这个字段既索引也存储,如果是TextReader的话只索引不存储,这点要搞清楚,另外在构建TextReader的时候要注意使用合适的编码格式,否则有的文件读出来是乱码,建立的索引肯定也是按乱码建立的咯。
【小节】
  其实lucene大家谁也是学学就会,关键要是整一个像google,baidu这样的搜索引擎就难了,好歹这搜索引擎也是一个行业呢,所以谁有兴趣,好好钻研一下搜索行业的相关技术,没准靠这个还能创业呢,是吧。
  再问一下,《lucence实战》有中文版吗?或者其它关于Lucence的中午图书,给推荐一本。
  最后借贵地和大家讨论一个问题:从长远考虑,程序员学那项技术比较有前途?做程序也好几年了,想找一个领域好好深入一下,以后做一个行业的领域专家。那样才不会太累,要不什么都鼓捣,太累了,而且还不容易出成绩。我列举了几个方向,大家帮忙分析分析,谢谢。
1、linux+oracle(走数据库管理的路线)
2、汇编、c底层驱动开发(据说很简单,就那么几个指令,学一年就精通了,不像.NET,得老跟着走)
3、ec++,kjava嵌入式开发(包括手机游戏,路由固件等开发)
4、即时通讯行业(网络编程,包括网络游戏的服务端编程这些)
5、搜索行业(不太了解)
6、OA、工作流(自己做一套不用编程,拖拖拽拽画画就能实现企业业务流程的电子化,infopath,OSS,formserver,WF的那一套)
7、.net网站开发(范围很大,要掌握的东西太多,会的人很多,深入的很少)
8、流媒体开发(3G时代这玩意儿不知道能不能派上用场)
【参考】
idior的《Lucene.net系列》
李刚、宋伟、邱哲的《ajax+lucene构建搜索引擎》

下载地址:
http://files.cnblogs.com/onlytiancai/WawaSearch.rar

posted @ 2006-10-16 09:56 蛙蛙王子 Views(15492) Comments(27) Edit 收藏

 回复 引用 查看   
#1楼2006-10-16 10:07 | Jason Cui      
本来我是用这个做我的数据库的全文检索的,但是读取每一条记录建立索引这个时间太长了,文章表17万记录,索引一次要2个小时,如果加上回复表100万记录,索引一次要8个小时。后来就放弃了。
 回复 引用 查看   
#2楼[楼主]2006-10-16 10:18 | 蛙蛙池塘      
那你现在用什么方案呀,有比lucene.net更快的索引库吗?还是用数据库自带的全文索引呀,不知道海量科技用的什么索引技术。
 回复 引用 查看   
#3楼2006-10-16 10:39 | 我不是一只鹿      
..............
 回复 引用   
#4楼2006-10-16 10:41 | kingcat1234[未注册用户]
to :<<lucence实战》有中文版吗?
只看到过别人翻译的一部分.英文的一样看啊,随便锻炼下英文阅读.呵呵

 回复 引用 查看   
#5楼[楼主]2006-10-16 10:43 | 蛙蛙池塘      
@kingcat1234
那你翻译我看吧,哈哈。

 回复 引用 查看   
#6楼2006-10-16 10:47 | 阿瑞      
我觉作网站还是创业的捷径,关键是要有出色的想法,技术其实不是关键
 回复 引用   
#7楼2006-10-16 11:10 | 阿好.net[匿名]
1、linux+oracle(走数据库管理的路线)
2、汇编、c底层驱动开发(据说很简单,就那么几个指令,学一年就精通了,不像.NET,得老跟着走)
3、ec++,kjava嵌入式开发(包括手机游戏,路由固件等开发)
4、即时通讯行业(网络编程,包括网络游戏的服务端编程这些)
5、搜索行业(不太了解)
6、OA、工作流(自己做一套不用编程,拖拖拽拽画画就能实现企业业务流程的电子化,infopath,OSS,formserver,WF的那一套)
7、.net网站开发(范围很大,要掌握的东西太多,会的人很多,深入的很少)
8、流媒体开发(3G时代这玩意儿不知道能不能派上用场)

其实核心内容,还是c++

 回复 引用 查看   
#8楼[楼主]2006-10-16 11:33 | 蛙蛙池塘      
关键c++门槛高呀,c++只是语言,要选个行业呀。我打算走DM和BI方面的方向
 回复 引用 查看   
#9楼2006-10-16 21:34 | kwklover      
@Jason Cui
我现在的就是用DotLucene做索引.虽然没有用到中文分词,但效果还是可以的.起码搜索速度很快.

你换个方式来索引啊?你每次读1000条,或者3000条,或者更多,只要你内存够大.然后在做索引.这样速度会快很多.因为一条一条从数据库读数据库肯定慢了.

 回复 引用 查看   
#10楼[楼主]2006-10-17 09:45 | 蛙蛙池塘      
@kwklover
lucene的索引性能优化是难点。

 回复 引用   
#11楼2006-10-17 18:22 | david8k[未注册用户]
@Jason Cui
不是可以开服务来建立索引吗

 回复 引用   
#12楼2006-10-17 18:23 | david8k[未注册用户]
参考一下Seekafile Server
 回复 引用 查看   
#13楼2006-10-19 10:52 | Jason Cui      
但是是否能够达到实时更新呢?比如我新建了一篇文章,或者修改/删除了一篇文章,怎样通知服务去更新呢?
 回复 引用 查看   
#14楼2006-10-22 17:17 | 曲滨      
Lucene 是啥?
 回复 引用   
#15楼2006-11-20 22:40 | aquila[匿名][未注册用户]
我用你的程序在在那四个原始文件中我加入了一些数字,为什么不能够被索引呢
?能给点提示吗?

 回复 引用   
#16楼2006-11-24 12:12 | davids[未注册用户]
可以试试Lucene的分布式索引.
分开索引,最后再合并索引

 回复 引用 查看   
#17楼2007-11-22 11:25 | ithurricane      
请问博主,现在已经找好方向了吗?

 回复 引用 查看   
#18楼[楼主]2007-12-03 20:49 | 蛙蛙池塘      
你好,我还想作KM
 回复 引用 查看   
#19楼2008-06-06 15:34 | 簡簡單單..      
Mark
 回复 引用   
#20楼2009-03-24 15:30 | na zili[未注册用户]
不知道什么原因我怎么测试不出来啊
 回复 引用 查看   
#21楼[楼主]2009-03-25 16:22 | 蛙蛙池塘      
啥?
 回复 引用 查看   
#22楼2009-12-16 09:35 | 大禹治水      
你好.net Lucene是不是经常出现SYSTEM.IO.FILENOTFOUND的异常?但是不影响使用?
 回复 引用   
#23楼2009-12-23 11:18 | yearyeah[未注册用户]
{"Lock obtain timed out: SimpleFSLock@E:\\indexpalce\\write.lock"}
[Lucene.Net.Store.LockObtainFailedException]: {"Lock obtain timed out: SimpleFSLock@E:\\indexpalce\\write.lock"}
Data: {System.Collections.ListDictionaryInternal}
HelpLink: null
HResult: -2146232800
InnerException: null
Message: "Lock obtain timed out: SimpleFSLock@E:\\indexpalce\\write.lock"
Source: "Lucene.Net"
StackTrace: " 在 Lucene.Net.Store.Lock.Obtain(Int64 lockWaitTimeout) 位置 E:\\WorkPlace\\TestSearch\\Lucene.Net\\Store\\Lock.cs:行号 107\r\n 在 Lucene.Net.Index.IndexWriter.Init(Directory d, Analyzer a, Boolean create, Boolean closeDir, IndexDeletionPolicy deletionPolicy, Boolean autoCommit) 位置 E:\\WorkPlace\\TestSearch\\Lucene.Net\\Index\\IndexWriter.cs:行号 739\r\n 在 Lucene.Net.Index.IndexWriter..ctor(String path, Analyzer a, Boolean create) 位置 E:\\WorkPlace\\TestSearch\\Lucene.Net\\Index\\IndexWriter.cs:行号 450\r\n 在 Test.Win.WriteIndex.IndexUtils.GetWriter() 位置 E:\\WorkPlace\\TestSearch\\Test.Win\\WriteIndex\\IndexUtils.cs:行号 65\r\n 在 Test.Win.WriteIndex.IndexUtils.IndexDirectory(List`1 doclists) 位置 E:\\WorkPlace\\TestSearch\\Test.Win\\WriteIndex\\IndexUtils.cs:行号 30\r\n 在 Test.Win.WriteIndex.WriteIndex.DoWriterIndex(DataTable dt) 位置 E:\\WorkPlace\\TestSearch\\Test.Win\\WriteIndex\\WriteIndex.cs:行号 40\r\n 在 Test.Win.Form1.dowork() 位置 E:\\WorkPlace\\TestSearch\\Test.Win\\Form1.cs:行号 50"
TargetSite: {Boolean Obtain(Int64)}

 回复 引用 查看   
#24楼2010-10-08 18:46 | 妖*小夜      
testing 关注博主呵呵呵
 回复 引用 查看   
#25楼2011-07-22 11:46 | 无拘无束      
06年的帖子了?不简单啊。呵呵 我们现在在用SOLR。但是还是觉得比LZ晚太多。
 回复 引用 查看   
#26楼2011-11-22 20:37 | ChesterQin      
@阿瑞
想法更不是关键