一、第一种删除方式
1、索引的创建、查询文档数的代码可以参考上两篇博文
2、删除索引代码
public void delete() { IndexWriter writer = null; try { writer = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_35,new StandardAnalyzer(Version.LUCENE_35))); //参数是一个选项,可以是一个Query,也可以是一个term,term是一个精确查找的值 //此时删除的文档并不会被完全删除,而是存储在一个回收站中的,可以恢复 writer.deleteDocuments(new Term("id","1")); writer.commit(); } 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(); } } }
3、测试结果
下面所获取的查询结果,是通过新的reader再进行查询的
与上面结果截图配套的查询代码
public void query() { try { IndexReader reader = IndexReader.open(directory); //通过reader可以有效的获取到文档的数量 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 (IOException e) { e.printStackTrace(); } }
如果想比较删除后没有开启新reader和开启后的查询差别?
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.commit(); 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(); } } }
测试代码
@Test public void testDelete() { IndexUtil iu = new IndexUtil(); iu.delete(); System.out.println("============="); iu.query(); }
结果截图
4、使用luke进行查看
(没有进行删除前)
(进行删除后)
二、第二种删除方式
1、代码
public void delete02() { try { reader.deleteDocuments(new Term("id","1")); 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(); } }
2、执行结果
如果想比较删除后没有开启新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()); reader.close(); } catch (CorruptIndexException e) { e.printStackTrace(); } catch (LockObtainFailedException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
测试代码
@Test public void testDelete02() { IndexUtil iu = new IndexUtil(); iu.delete02(); System.out.println("============="); iu.query(); }
结果截图
3、两种删除方式的区别
(注:以下摘自《Lucene 实战》)
1、IndexReader能够根据文档号删除文档,这意味着你可以通过搜索操作逐步跟踪文档号,可能需要执行一些程序逻辑,然后选出将被删除的文档号。对于IndexWriter来说尽管已经被要求多次,但是还不能提供这样一个方法,因为档号可能因为段合并操作而立即发生改变。
2、IndexReader可以通过Term对象删除文档,这样IndexWriter类似,但是IndexReader会返回被删除的文档数,而IndexWriter则不能。这是因为两者的实现存在差异:IndexReader可以立即决定删除哪个文件,因此就能够对这些文档数量进行计算;而IndexWriter仅仅是将被删除的Term进行缓存,后续再进行实际的删除操作。
3、如果程序使用相同的reader进行搜索的话,IndexReader的删除操作会立即生效,这意味你可以在删除操作后立即进行搜索操作,并会发现被删除文档已经不会出现在搜索结果中了,如果使用IndexWriter,这种删除操作必须等到程序打开一个新的Reader才能被感知。
4、IndexWriter可以通过Query对象执行删除操作,但是IndexReader则不行(尽管运行自己的Query并简单删除由Query返回的文档号并不困难)。