Lucene知识小总结3:索引的删除

一、第一种删除方式

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、测试结果

210527_qaiB_1417419.png

下面所获取的查询结果,是通过新的reader再进行查询的

210527_euG9_1417419.png

与上面结果截图配套的查询代码

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();
	}

结果截图

215010_7OjB_1417419.png

4、使用luke进行查看

(没有进行删除前)

210621_dzhx_1417419.png

210624_Y2Pr_1417419.png

(进行删除后)

210700_47g1_1417419.png

210701_Tor9_1417419.png

二、第二种删除方式

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();
	}

结果截图

215218_UnEI_1417419.png

3、两种删除方式的区别

(注:以下摘自《Lucene 实战》)

1、IndexReader能够根据文档号删除文档,这意味着你可以通过搜索操作逐步跟踪文档号,可能需要执行一些程序逻辑,然后选出将被删除的文档号。对于IndexWriter来说尽管已经被要求多次,但是还不能提供这样一个方法,因为档号可能因为段合并操作而立即发生改变。

223113_1gkO_1417419.png

223117_kc37_1417419.png

2、IndexReader可以通过Term对象删除文档,这样IndexWriter类似,但是IndexReader会返回被删除的文档数,而IndexWriter则不能。这是因为两者的实现存在差异:IndexReader可以立即决定删除哪个文件,因此就能够对这些文档数量进行计算;而IndexWriter仅仅是将被删除的Term进行缓存,后续再进行实际的删除操作。

3、如果程序使用相同的reader进行搜索的话,IndexReader的删除操作会立即生效,这意味你可以在删除操作后立即进行搜索操作,并会发现被删除文档已经不会出现在搜索结果中了,如果使用IndexWriter,这种删除操作必须等到程序打开一个新的Reader才能被感知。

4、IndexWriter可以通过Query对象执行删除操作,但是IndexReader则不行(尽管运行自己的Query并简单删除由Query返回的文档号并不困难)。

223144_bF8k_1417419.png

223145_heMr_1417419.png


转载于:https://my.oschina.net/heroShane/blog/202326

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值