1、问题:
目前索引里面已经有1000多万的数据了,现在需要每几分钟就增量得添加新的内容到索引中。
但是,我发现新加入索引后,整个索引结构都要重新调整。非常耗时(长达半个小时)。
不知道大家有没有什么比较好的办法,加快这个过程?
回答:
我觉得用lucene做,一个原则索引里面尽量少存储,索引文件小了,optimize要移动的数据块也小。
还有Lucene实在不适合做实时,有一个办法,将新索引建在内存中,新建在内存上的searcher与硬盘索引searcher合并为MutliSearcher提供给前端搜索,
内存到达一定量时再后台合并到主索引上,合并完成用新的Searcher替换MutliSearcher。 --来自网络,仅供学习
RAMDirectory和FSDirectory相结合使用
//创建基于RAMDirectory的索引
RAMDirectory rd = new RAMDirectory();
IndexWriter iw = new IndexWriter(rd,new StandardAnalyzer());
….
//向基于RAMDirectory的索引中添加文档
iw.addDocument(doc);
iw.close();
//建立基于FSDirectory的索引
FSDirectory fd = FSDirectory.getDirectory("mix");
IndexWriter writer = new IndexWriter(fd,new StandardAnalyzer());
//把缓存在RAMDirectory中的所有数据写入FSDirectory
writer.addIndexes(new Directory[] {rd});
writer.close();
同样可以反过来用,将文件系统中的索引读入内存中,就需要使用如下的方法:
RAMDirectory rd=new RAMDirectory();
2、上周在使用范围搜索时又遇到问题 ,程序抛出TooManyClauses exception。后来才发现lucene将范围搜索转化为精确匹配,每个匹配对应一个clause,所以如果你的范围如果包含超过1024个索引值,程序就会抛错
方案1:BooleanQuery.setMaxClauseCount(Integer.MAX_VALUE)
改变限制,这个可以解决问题,但有隐患,如果某个范围的索引特别多,内存会有爆掉的危险。
方案2:使用filter--来自网络,仅供学习
3、昨天改了一个晚上代码都无法使搜索引擎创建文件索引到硬盘中,经过调试发觉已经把文档、字段提取到了内存索引器中,然而在把内存索引书写器中的索引传递给硬盘索引书写器时似乎没有传送成功,
只出现segments.gen和segments_2。单独使用FSDirectory时,却是在硬盘相应目录中能够看到索引文件啊!
fsWriter.addIndexesNoOptimize(Directory[] {ramdir});
明明已经写上了这句了啊?第二天上午翻翻资料,发觉有一份资料强调:在合并内存索引器的索引到硬盘索引器前,务必先关闭内存索引器。于是我试着在前面加上"ramWriter.close();",果然终于出现了久违的.cfs文件。
这个问题的关键是在任何时候对索引的更新操作的实例只能有一个存在