IndexReader提供了一个有时非常有用的方法undeleteAll,该方法能反向操作索引中所有被挂起的删除。需要注意的是,该方法只能对还未进行段合并的文档进反删除操作。该方法之所以能够实现反删除操作,是因为IndexWriter只能将删除文档标志为删除状态,但事实上并未真正移除这些文档,最终的删除操作是在该文档所对应的段进行合并时才执行的。(以上文字摘自《Lucene 实战》)
一、下面代码使用reader进行删除
public void delete02() {
try {
reader = IndexReader.open(directory,false);
reader.deleteDocuments(new Term("id","1"));
System.out.println("numDocs:"+reader.numDocs());
System.out.println("maxDocs:"+reader.maxDoc());
System.out.println("deleteDocs:"+reader.numDeletedDocs());
System.out.println("=============");
reader.undeleteAll();
System.out.println("numDocs:"+reader.numDocs());
System.out.println("maxDocs:"+reader.maxDoc());
System.out.println("deleteDocs:"+reader.numDeletedDocs());
reader.close();
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (LockObtainFailedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
执行结果截图
二、下面代码使用writer进行删除
public void delete() {
IndexWriter writer = null;
try {
reader = IndexReader.open(directory,false);
writer = new IndexWriter(directory,
new IndexWriterConfig(Version.LUCENE_35,new StandardAnalyzer(Version.LUCENE_35)));
//参数是一个选项,可以是一个Query,也可以是一个term,term是一个精确查找的值
//此时删除的文档并不会被完全删除,而是存储在一个回收站中的,可以恢复
//writer.deleteDocuments(new Term("id","1"));
writer.deleteDocuments(new Term("id","1"));
writer.commit();
System.out.println("numDocs:"+reader.numDocs());
System.out.println("maxDocs:"+reader.maxDoc());
System.out.println("deleteDocs:"+reader.numDeletedDocs());
reader.close();
reader = IndexReader.open(directory,false);
System.out.println("=============");
System.out.println("numDocs:"+reader.numDocs());
System.out.println("maxDocs:"+reader.maxDoc());
System.out.println("deleteDocs:"+reader.numDeletedDocs());
System.out.println("=============");
//writer.close();
reader.undeleteAll();
System.out.println("numDocs:"+reader.numDocs());
System.out.println("maxDocs:"+reader.maxDoc());
System.out.println("deleteDocs:"+reader.numDeletedDocs());
reader.close();
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (LockObtainFailedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(writer!=null) writer.close();
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行报错
把”writer.close();“的注释去掉再运行
查阅资料,可以作为借鉴的解析:
如果你试图通过IndexReader删除文档,需要记住:Lucene只允许一个writer打开一次。实施删除操作的IndexReader此时只能算作一个writer。这意味着在使用IndexReader进行删除操作之前必须关闭已打开的任何IndexWriter,反之亦然。