/**
* 更新索引
* @see Lucene其实并未提供更新索引的方法,这里的更新操作内部是先删除再添加的方式
* @see 因为Lucene认为更新索引的代价,与删除后重建索引的代价,二者是差不多的
*/
public void updateIndex(){
IndexWriter writer = null;
Document doc = new Document();
try{
writer = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_36, new StandardAnalyzer(Version.LUCENE_36)));
doc.add(new Field("id", "1111", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
doc.add(new Field("name", names[0], Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
doc.add(new Field("email", emails[0], Field.Store.YES, Field.Index.NOT_ANALYZED));
doc.add(new Field("content", contents[0], Field.Store.NO, Field.Index.ANALYZED));
doc.add(new NumericField("attach", Field.Store.YES, true)。setIntValue(attachs[0]));
doc.add(new NumericField("date", Field.Store.YES, true)。setLongValue(dates[0].getTime()));
//其实它会先删除索引文档中id为1的文档,然后再将这里的doc对象重新索引,所以即便这里的1!=1111,但它并不会报错
//所以在执行完该方法后:maxDocs=7,numDocs=6,deletedDocs=1,就是因为Lucene会先删除再添加
writer.updateDocument(new Term("id","1"), doc);
}catch(Exception e) {
e.printStackTrace();
}finally{
if(null != writer){
try {
writer.close();
} catch (IOException ce) {
ce.printStackTrace();
}
}
}
}
/**
* 删除索引
* @see -----------------------------------------------------------------------------------------------------
* @see 在执行完该方法后,再执行本类的searchFile()方法,得知numDocs=5,maxDocs=6,deletedDocs=1
* @see 这说明此时删除的文档并没有被完全删除,而是存储在一个回收站中,它是可以恢复的
* @see -----------------------------------------------------------------------------------------------------
* @see 从回收站中清空索引IndexWriter
* @see 对于清空索引,Lucene3.5之前叫做优化,调用的是IndexWriter.optimize()方法,但该方法已被禁用
* @see 因为optimize时它会全部更新索引,这一过程所涉及到的负载是很大的,于是弃用了该方法,使用forceMerge代替
* @see 使用IndexWriter.forceMergeDeletes()方法可以强制清空回收站中的内容
* @see 另外IndexWriter.forceMerge(3)方法会将索引合并为3段,这3段中的被删除的数据也会被清空
* @see 但其在Lucene3.5之后不建议使用,因为其会消耗大量的开销,而Lucene会根据情况自动处理的
* @see -----------------------------------------------------------------------------------------------------
*/
public void deleteIndex(){
IndexWriter writer = null;
try{
writer = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_36, new StandardAnalyzer(Version.LUCENE_36)));
//其参数可以传Query或Term…Query指的是可以查询出一系列的结果并将其全部删掉,而Term属于精确查找
writer.deleteDocuments(new Term("id", "1")); //删除索引文档中id为1的文档
}catch(Exception e) {
e.printStackTrace();
}finally{
if(null != writer){
try {
writer.close();
} catch (IOException ce) {
ce.printStackTrace();
}
}
}
}
/**
* 恢复索引
* @see 建议弃用
*/
@Deprecated
public void unDeleteIndex(){
IndexReader reader = null;
try {
//IndexReader.open(directory)此时该IndexReader默认的readOnly=true,而在恢复索引时应该指定其为非只读的
reader = IndexReader.open(directory, false);
//Deprecated. Write support will be removed in Lucene 4.0. There will be no replacement for this method.
reader.undeleteAll();
} catch (Exception e) {
e.printStackTrace();
}finally{
if(null != reader){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
下面是用JUnit4.x写的一个小测试
双击代码全选
package com.jadyer.test;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.jadyer.lucene.HelloIndex;
public class HelloIndexTest {
private HelloIndex hello;
@Before
public void init(){
hello = new HelloIndex();
}
@After
public void destroy(){
hello.getDocsCount();
}
@Test
public void createIndex(){
hello.createIndex();
}
@Test
public void searchFile(){
hello.searchFile();
}
@Test
public void updateIndex(){
hello.updateIndex();
}
@Test
public void deleteIndex(){
hello.deleteIndex();
}
@Test
@SuppressWarnings("deprecation")
public void unDeleteIndex(){
hello.unDeleteIndex();
}
}