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

Lucene知识小总结3:索引的删除_第1张图片

下面所获取的查询结果,是通过新的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();
	}

结果截图

Lucene知识小总结3:索引的删除_第2张图片

4、使用luke进行查看

(没有进行删除前)

Lucene知识小总结3:索引的删除_第3张图片

Lucene知识小总结3:索引的删除_第4张图片

(进行删除后)

Lucene知识小总结3:索引的删除_第5张图片

Lucene知识小总结3:索引的删除_第6张图片

二、第二种删除方式

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

结果截图

Lucene知识小总结3:索引的删除_第7张图片

3、两种删除方式的区别

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

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

Lucene知识小总结3:索引的删除_第8张图片

Lucene知识小总结3:索引的删除_第9张图片

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

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

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

Lucene知识小总结3:索引的删除_第10张图片

Lucene知识小总结3:索引的删除_第11张图片


你可能感兴趣的:(Lucene)