Lucene索引删除详解

 如下索引,NameCount读出来是2,说明新的段位_2.xxx,_2.yyy

lucene索引 段

  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
  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值