如下索引,NameCount读出来是2,说明新的段位_2.xxx,_2.yyy
SegCount
段(Segment)的个数。
如上图,此值为2。
SegCount元数据信息:
SegName
段名,所有属于同一个段的文件都有以段名作为文件名。
如上图:第一个段的段名为“_0”,第二个段的段名为“_1”。
SegSize
此段中包含的文档数
然而此文档数是包括已经删除,又没有optimize的文档的,因为在optimize之前,Lucene的段中包含了所有被索引过的文档,而被删除的文档是保存在.del文件中的,在搜索过程中,是先从段中读到了被删除的文档,然后再用.del中的标志,将这篇文档过滤掉。
如下的代码形成了上图的索引,可以看出索引了两篇文档形成了_0段,然后又删除了其中一篇,形成了_0_1.del,又索引了两篇文档形成_1段,然后又删除了其中一篇,形成了_1_1.del。因而在两个段中,此值都是2。
IndexWriter writer = new IndexWrite(FSDirectory.open(INDEX_DIR),
new StandardAnalyzer(Version.LUCENE_CURRENT),
true,
IndexWriter.MaxFieldLength.LIMITED);
writer.setUseCompoundFile(false);
indexDocs(writer,docDir);//docDir中只有两篇文档
//文档一位:Students should be allowed to go out with their friends,but not allowed to drink beer
//文档二:my friend jerry went to school to see his students but not found them drunk which is not allowed.
writer.commit();//提交两篇文档,形成_0段。
writer.deleteDocuments(new Term("contents","school"));//删除文档二
writer.commit();//提交删除,形成_0_1.del
indexDocs(writer,docDir);//再次索引两篇文档,Lucene不能判别文档与文档的不同,因而算两篇新的文档。
writer.commit();//提交两篇文档,形成_1段
writer.deleteDocuments(new Term("contents","school"));// 删除第二次添加的文档二
writer.close();//提交删除,形成_1_1.del
。DelGen
1、.del文件的版本号
2、lucene中,在optimize之前,删除的文档是保存在.del文件中的。
3、在lucene2.9中,文档删除有以下几种方式:
IndexReader.deleteDocument(int docID)是用IndexReader 按文档号删除。
IndexReader.deleteDocuments(Term term)是用IndexReader删除包含此词(Term)的文档。
IndexWriter.deleteDocuments(Term term)是用IndexWriter删除包含此词(Term)的文档。
IndexWriter.deleteDocuments(Term[] terms)IndexWriter批量删除文档。
IndexWriter.deleteDocuments(Query query)删除满足query查询的文档。
IndexWriter.deleteDocuments(Query[] queries)删除满足多个查询数组的文档。
原来的版本中Lucene的删除一直是由IndexReader来完成的,在Lucene2.9中虽可以用IndexWriter来删除,但是其真实的实现是在IndexWriter中保存了readerpool,当IndexWriter向索引文件提交删除的时候,仍然是从readerpool中得到相应的IndexReader,并用IndexReader来进行删除的,下面的代码可以说明:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
IndexWriter.applyDeletes()
->DocumentsWriter.applyDeletes(SegmentInfos)
->reader.deleteDocument(doc);
//DelGen是每当IndexWriter向索引文件提交删除操作的时候,加1,并生成新的.del文件。
IndexWriter.commit()
->IndexWriter.applyDeletes()
->IndexWriter$ReaderPool.release(SegmentReader)
->SegmentReader(IndexReader).commit()
->SegmentReader.doCommit(Map)
->SegmentInfo.advanceDeGen()
->
if
(delGen==NO){
delGen=YES;
}
else
{
delGen++;
}
IndexWriter writer=
new
IndexWriter(FSDirectory.open(INDEX_DIR),
new
StandardAnalyzer(Version.LUCENE_CURRENT),
true
,IndexWriter.MaxFieldLenth.LIMITED);
writer.setUseCompoundFile(
false
);
indexDoc(writer,docDir);
//索引两篇文档,一篇包含"school",另一篇包含"beer"
writer.commit();
//提交两篇文档到索引文件,形成段(Segment)"_0"
writer.deleteDocuments(
new
Term(
"contents"
,
"school"
));
//删除包含"school"的文档,其实是
删除了两篇文档中的一篇。
writer.commit();
//提交删除到索引文件,形成"_0_1.del"
writer.deleteDocuments(
new
Term(
"contents"
,
"beer"
));
//删除包含"beer"的文档,其实是删
除了两篇文档中的另一篇。
writer.commit();
//提交删除到索引文件,形成"_0_2.del"
indexDocs(writer, docDir);
//索引两篇文档,和上次的文档相同,但是Lucene无法区分,认为是
另外两篇文档。
writer.commit();
//提交两篇文档到索引文件,形成段"_1"
writer.deleteDocuments(
new
Term(
"contents"
,
"beer"
));
//删除包含"beer"的文档,其中段"_0"已经无可删除,段"_1"被删除一篇。writer.close();//提交删除到索引文件,形成"_1_1.del"
|
1
|
形成索引文件如下:
|
1
|
|