public void delete() {
IndexWriter indexWriter = null;
try {
indexWriter = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_35, new StandardAnalyzer(Version.LUCENE_35)));
// 参数是一个选项,可以是一个Query(查找的一个范围),也可以是一个Term(一个精确的查找值)
// 此时文档没有被彻底删除,只是放在了回收站中
indexWriter.deleteDocuments(new Term("id", "1"));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (indexWriter != null) {
try {
indexWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void query() {
try {
IndexReader indexReader = IndexReader.open(directory);
// numDocs()返回索引中未被删除的文档总数
// maxDoc()返回索引中删除(标记为删除,但是还没有真正删除)和未被删除的文档总数
// numDeleteDocs()返回被放在回收站的索引的数目,这些是可以恢复的
System.out.println("numDocs=" + indexReader.numDocs());
System.out.println("maxDocs=" + indexReader.maxDoc());
System.out.println("numDeleteDocs=" + indexReader.numDeletedDocs());
} catch (IOException e) {
e.printStackTrace();
} finally {
if(indexReader!=null){
try {
indexReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
这里的删除并没有完全删除,而是放在了“回收站”,通过query方法可以看到,maxDocs不等于numDocs的,并且numDeleteDocs的值就是刚刚被删除的数目,被删除的这个索引是可以恢复的。
public void undelete() {
// 使用IndexReader来恢复
try {
// IndexReader默认是用来读索引的,现在要用IndexReader来写(恢复)索引,需要添加一个参数readOnly,默认情况是true,我们需要指定成false
IndexReader indexReader = IndexReader.open(directory, false);
indexReader.undeleteAll();
indexReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void query() {
try {
IndexReader indexReader = IndexReader.open(directory);
// numDocs()返回索引中未被删除的文档总数
// maxDoc()返回索引中删除(标记为删除,但是还没有真正删除)和未被删除的文档总数
// numDeleteDocs()返回被放在回收站的索引的数目,这些是可以恢复的
System.out.println("numDocs=" + indexReader.numDocs());
System.out.println("maxDocs=" + indexReader.maxDoc());
System.out.println("numDeleteDocs=" + indexReader.numDeletedDocs());
} catch (IOException e) {
e.printStackTrace();
} finally {
if(indexReader!=null){
try {
indexReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
使用IndexReader来进行恢复,需要多指定一个readOnly参数,否则会报错。undelete()之后,再去执行query(),就可以发现被删除的索引恢复了。
public void forceDelete() {
IndexWriter indexWriter = null;
try {
indexWriter = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_35, new StandardAnalyzer(Version.LUCENE_35)));
indexWriter.forceMergeDeletes();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (indexWriter != null) {
try {
indexWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void query() {
try {
IndexReader indexReader = IndexReader.open(directory);
// numDocs()返回索引中未被删除的文档总数
// maxDoc()返回索引中删除(标记为删除,但是还没有真正删除)和未被删除的文档总数
// numDeleteDocs()返回被放在回收站的索引的数目,这些是可以恢复的
System.out.println("numDocs=" + indexReader.numDocs());
System.out.println("maxDocs=" + indexReader.maxDoc());
System.out.println("numDeleteDocs=" + indexReader.numDeletedDocs());
} catch (IOException e) {
e.printStackTrace();
} finally {
if(indexReader!=null){
try {
indexReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
先执行delete(),再执行forceDelete(),再次查询发现numDeleteDocs是0,numDocs和maxDocs都比前面少1,意味着回收站中的索引彻底被删除了 。
public void merge() {
IndexWriter indexWriter = null;
try {
indexWriter = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_35, new StandardAnalyzer(Version.LUCENE_35)));
// 会将索引合并为两段,这两段中被删除的数据会被清空
// 在Lucene3.5之后不建议使用,因为会浪费大量的开销,Lucene会根据情况自动处理
indexWriter.forceMerge(2);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (indexWriter != null) {
try {
indexWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
不建议使用,因为会损耗比较大的性能,这里就不过多研究了。
public void update() {
IndexWriter indexWriter = null;
try {
indexWriter = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_35, new StandardAnalyzer(Version.LUCENE_35)));
// Lucene的更新其实是先删除后添加
Document document = new Document();
document.add(new Field("id", "11", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
document.add(new Field("email", emails[0], Field.Store.YES, Field.Index.NOT_ANALYZED));
document.add(new Field("content", contents[0], Field.Store.NO, Field.Index.ANALYZED));
document.add(new Field("name", names[0], Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
indexWriter.updateDocument(new Term("id", "1"), document);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (indexWriter != null) {
try {
indexWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Lucene中的更新分为两步进行:先删除,后添加,通过上面的例子可以看出来,更新id为1的文档,更新后的文档id也可以发生变化,所以说是先删除,后添加。为了进一步验证,可以执行query()方法,会发现numDeleteDocs是1,也就是发生了删除操作,再一次证实了这个观点。