2012-10-17
最早lucene2.4以及以前,追溯到2008年前后,lucene刚刚引起大家的关注,到后来Nutch、solr的出现,lucene变得更加热。Nutch、Solr的发展,极大推动了lucene的升级。对于一些接触过搜索,使用过lucene、solr的人来说,一般都会感觉lucene、solr很牛逼。我个人也认为solr、lucene确实非常NB,他涵盖了信息检索的几乎全部基础知识和非常高性能的实现方式。从solr的结构,扩展、维护整体看,发现有非常多的“工程亮点”,熟读solr定会增加对java的理解、运用技能。
阅读全文 »
2012-10-15
今天帮群里一个同学解决索引生成时间过长的问题,15万的数据生成结果需要半小时,通过逐步排查,结果定位到索引生成的部分,原来网上很多的例子写的笔记简单,在生成的时候没有仔细考虑速度,直接在添加文档生成索引时候就用了writer.optimize();结果每一次提交都合并索引,这样性能会极大的降低,真正的生产环境下需要 循环 writer.AddDocument(doc);,然后
finally {
writer.Optimize();
writer.Close();
}
这样生成索引最后一次合并,从原来的半小时缩小到7秒钟,15万条记录从7秒钟,如果是150万是不是70秒,1500万700秒,肯定不是,1500万需要进一步多线程去优化才行了,而且也不只700秒了。
以上是对lucene的opimize的简单理解,事实比这复杂。
阅读全文 »
2012-10-12
lucene searchAfter 这种分页方法应该只支持3.5以上版本,以下是lucene分页代码,只实现的最重要的分页部分,获取总记录数略去了。
阅读全文 »
2012-06-07
orchard是微软自己团队搞的cms,园子里有很多园友已经对系统结构详细分析了,但是对里面的某些模块没有一一分析,因为需要使用lucene.net做站内搜索,所以参考学习一下,ps一下lucene.net已经是2.9.4版本了,虽然还在孵化器,但是还是更新了,不容易啊。
阅读全文 »
2012-06-04
代码为:
DocWriter perDoc = state.consumer.processDocument();
每一个文档集处理对象DocumentsWriterThreadState都有一个文档及域处理对象
DocFieldProcessorPerThread,它的成员函数processDocument()被调用来对文档及域进行处理。
线程索引链(XXXPerThread):
由于要多线程进行索引,因而每个线程都要有自己的索引链,称为线程索引链。
线程索引链同基本索引链有相似的树形结构,由基本索引链中每个层次的对象调用addThreads进行创建的,负责每个
文档的处理。
阅读全文 »
2012-06-04
DocumentsWriterThreadState state = getThreadState(doc, delTerm);
在Lucene中,对于同一个索引文件夹,只能够有一个IndexWriter打开它,在打开后,在文件夹中,生成文件
write.lock,当其他IndexWriter再试图打开此索引文件夹的时候,则会报
org.apache.lucene.store.LockObtainFailedException错误。
这样就出现了这样一个问题,在同一个进程中,对同一个索引文件夹,只能有一个IndexWriter打开它,因而如
果想多线程向此索引文件夹中添加文档,则必须共享一个IndexWriter,而且在以往的实现中,addDocument
函数是同步的(synchronized),也即多线程的索引并不能起到提高性能的效果。
于是为了支持多线程索引,不使IndexWriter成为瓶颈,对于每一个线程都有一个相应的文档集处理对象
(DocumentsWriterThreadState),这样对文档的索引过程可以多线程并行进行,从而增加索引的速度。
getThreadState函数是同步的(synchronized),DocumentsWriter有一个成员变量threadBindings,它是一
个HashMap,键为线程对象(Thread.currentThread()),值为此线程对应的DocumentsWriterThreadState
象。
DocumentsWriterThreadState DocumentsWriter.getThreadState(Document doc, Term delTerm)包含
下几个过程:
• 根据当前线程对象,从HashMap中查找相应的DocumentsWriterThreadState对象,如果没找到,则
生成一个新对象,并添加到HashMap中
DocumentsWriterThreadState state = (DocumentsWriterThreadState) threadBindings.get(Thread.cu
if (state == null) {
……
state = new DocumentsWriterThreadState(this);
……
threadBindings.put(Thread.currentThread(), state);
}
• 如果此线程对象正在用于处理上一篇文档,则等待,直到此线程的上一篇文档处理完。
DocumentsWriter.getThreadState() {
waitReady(state);
state.isIdle = false;
}
waitReady(state) {
while (!state.isIdle) {wait();}
}
显然如果state.isIdle为false,则此线程等待。
在一篇文档处理之前,state.isIdle = false会被设定,而在一篇文档处理完毕之后,
DocumentsWriter.finishDocument(DocumentsWriterThreadState perThread, DocWriter docWriter)中,会首
perThread.isIdle = true; 然后notifyAll()来唤醒等待此文档完成的线程,从而处理下一篇文档。
• 如果IndexWriter刚刚commit过,则新添加的文档要加入到新的段中(segment),则首先要生成新的段
名。
initSegmentName(false);
--> if (segment == null) segment = writer.newSegmentName();
• 将此线程的文档处理对象设为忙碌:state.isIdle = false;
阅读全文 »
2012-06-03
lucene文档之DocumentsWriter
阅读全文 »
2012-06-01
lucene将文档加入IndexWriter
阅读全文 »
2012-05-11
Document对象主要包括以下部分:
此文档的boost,默认为1,大于一说明比一般的文档更加重要,小于一说明更不重要。
一个ArrayList保存此文档所有的域
每一个域包括域名,域值,和一些标志位,和fnm,fdx,fdt中的描述相对应。
阅读全文 »