为什么我的luncene3.6建索引时,一些中间文件没删除,没有形成cfs文件
用的是luncene3.6,
import java.io.File;
import java.io.IOException;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.store.LockObtainFailedException;
public class testluncene {
static IndexWriter indexWriter = null;
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
File indexDir = new File("d:\\testindex"); // 存放
// 检索文件的路径
if (!indexDir.exists()) {
indexDir.mkdirs();
}
Analyzer luceneAnalyzer = new IKAnalyzer();
IndexWriterConfig indexWriterConfig = new IndexWriterConfig(
Version.LUCENE_36, luceneAnalyzer);
try {
indexWriter = new IndexWriter(FSDirectory.open(indexDir),
indexWriterConfig);
Document document = new Document();
Field FieldName = new Field("ename", "我是谁",
Field.Store.YES, Field.Index.ANALYZED);
// 仅存储,不索引
Field FieldDesc = new Field("edesc", "你好,这是测试",
Field.Store.YES, Field.Index.NO);
document.add(FieldName);
document.add(FieldDesc);
indexWriter.addDocument(document);
indexWriter.close();
} catch (CorruptIndexException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (LockObtainFailedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
建完有 _0.fdt,_0.fdx,_0.fnm,_0.frq,_0.nrm,_0.prx,_0.tii,_0.tis,segments.gen,segments_1 这些文件,没有形成 cfs.文件,不知道怎么回事,是哪里设错了,请大家指点,谢谢!!
[解决办法]
以前就版本可以直接通过在IndexWriter上设置是否使用复合索引文件,像这样:
indexWriter.setUseCompoundFile(true);
3.6版本已经不建议这样做了,但是Lucene默认的策略会生成符合索引文件(cfs),这个优化可以减少加载Lucene索引时打开文件数(句柄)。
实际将这个配置项合并到MergePolicy里面去了,而一个MergePolicy实例可以通过IndexWriterConfig来配置,配置大概像这样:
MergePolicy mergePolicy = ...;
mergePolicy.useCompoundFile(arg0, arg1);
indexWriterConfig.setMergePolicy(mergePolicy);
另外,你上面程序是可以生成cfs符合索引文件的,只是你的数据少了点,可以这样试试:
for(int i=0; i<1000000; i++) {
Document document = new Document();
Field FieldName = new Field("ename", "我是谁" + i*i, Field.Store.YES,
Field.Index.ANALYZED);
// 仅存储,不索引
Field FieldDesc = new Field("edesc", "你好,这是测试" + 55*i, Field.Store.YES,
Field.Index.NO);
document.add(FieldName);
document.add(FieldDesc);
indexWriter.addDocument(document);
}
_17.fdx _17.tis _1i.prx _1t.frq _24.fdx _24.tis _2f.prx _2q.frq _3c.cfs _3x.fnm _43.cfs _4s.cfs _4y.cfs _b.fnm _l.fdt _l.tii _w.nrm
_17.fnm _1i.fdt _1i.tii _1t.nrm _24.fnm _2f.fdt _2f.tii _2q.nrm _3n.cfs _3x.frq _48.cfs _4t.cfs _4z.cfs _b.frq _l.fdx _l.tis _w.prx
_17.frq _1i.fdx _1i.tis _1t.prx _24.frq _2f.fdx _2f.tis _2q.prx _3o.cfs _3x.prx _4c.cfs _4u.cfs _50.fdt _b.nrm _l.fnm _w.fdt write.lock
_17.nrm _1i.fnm _1t.fdt _1t.tii _24.nrm _2f.fnm _2q.fdt _2q.tii _3r.cfs _3x.tii _4i.cfs _4v.cfs _50.fdx _b.prx _l.frq _w.fdx _w.tii
_17.prx _1i.frq _1t.fdx _1t.tis _24.prx _2f.frq _2q.fdx _2q.tis _3x.fdt _3x.tis _4o.cfs _4w.cfs _b.fdt _b.tii _l.nrm _w.fnm _w.tis
[解决办法]
什么叫临时文件???
fnm,tii,fdt等等都是索引文件。
新版本在索引的时候会根据实际数据的情况自动合并的,一般不需要你手动去干预。
不过有一点,cfs文件越大,索引消耗的时间就越多,对于海量数据的应用,这个时间开销可以通过使用高配机器来提高吞吐量。
实际上cfs是把多个段的索引合并了,你可以这样看,一个cfs文件包含了多个索引段(_X,X相同的多个文件为一个段)
因为lucene在内存中重建的时候,每个索引文件对应着打开的文件句柄,如果索引文件不合并,就会出现大量的文件句柄,有可能超过系统最大打开文件数,导致索引数据加载失败。
建议多看看Lucene方面的文档吧,把基本的概念和理论搞清楚。