Lucene整理--索引的管理

来源:转载


看lucene主页(http://lucene.apache.org/)上目前lucene已经到4.9.0版本了, 参考学习的书是按照2.1版本讲解的,写的代码例子是用的3.0.2版本的,版本

的不同导致有些方法的使用差异,但是大体还是相同的。

源代码用到的jar包(3.0.2版本)下载地址

参考资料:

1、公司内部培训资料

2、《Lucene搜索引擎开发权威经典》于天恩著.

Lucene使用挺简单的,耐心看完都能学会,还有源代码。

昨天建立了一个简单的索引,今天总结下怎么查看索引、更新索引和删除索引。

一、查看索引的信息

查看索引大体有三种方法:

1、使用IndexWriter类读取索引的相关信息

使用IndexWriter类可以得到索引的一些相关信息:

获取索引的目录信息:IndexWriter.getDirectory().toString();

获取索引的分析器:IndexWriter.getAnalyzer().toString();

总之是通过IndexWriter的相关方法获取索引的相关信息,具体可以查阅API文档。

2、使用IndexReader及其子类获取索引的相关信息

注意:例子当中没有创建索引,用到的索引是上文创建的

(1)、通过IndexReader类获取索引的基本信息

import java.io.File;import java.io.IOException;import java.util.Date;import org.apache.lucene.index.CorruptIndexException;import org.apache.lucene.index.IndexReader;import org.apache.lucene.store.Directory;import org.apache.lucene.store.SimpleFSDirectory;public class LuceneIndexReaderTest1 { public static void main(String[] args) { File indexDir = new File("E://Index"); try { Directory dir = new SimpleFSDirectory(indexDir); IndexReader ir= IndexReader.open(dir); //indexExists()方法 判断索引是否存在 if(ir.indexExists(dir)){ System.out.println("该索引存在!!"); }else{ System.out.println("该索引不存在!!"); } //lastModified()方法 返回指定目录上的索引上次修改的时间(毫秒形式) Date d=new Date(ir.lastModified(dir)); System.out.println(d); //isOptimized() 检查指标是否是最佳的 System.out.println(ir.isOptimized()); //directory() 获得索引目录 System.out.println(ir.directory()); //numDocs() 索引中文档数量 System.out.println(ir.numDocs()); // maxDoc() 返回索引可用的最大索引ID System.out.println(ir.maxDoc()); //close()关闭 ir.close(); } catch (CorruptIndexException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}

(2)、读取索引文档相关的基本信息,读取文档中的字段

import java.io.File;import java.io.IOException;import java.util.Date;import org.apache.lucene.document.Document;import org.apache.lucene.document.Field;import org.apache.lucene.index.CorruptIndexException;import org.apache.lucene.index.IndexReader;import org.apache.lucene.store.Directory;import org.apache.lucene.store.SimpleFSDirectory;public class LuceneIndexReaderTest2 { public static void main(String[] args) { File indexDir = new File("E://Index"); try { Directory dir = new SimpleFSDirectory(indexDir); IndexReader ir= IndexReader.open(dir); int num=ir.numDocs(); System.out.println(num); System.out.println("--------------------------------"); //Document相关信息 Document doc=ir.document(5);//5代表document的索引ID System.out.println(doc); System.out.println("--------------------------------"); for(int i=0 ; i<num; i++){ doc=ir.document(i); Field field=doc.getField("bookname");//获取每个doc中的field System.out.println(field.stringValue());//输出字段的值 System.out.println("--------------------------------"); } } catch (CorruptIndexException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}

二、删除索引中的文档

如果文档中某个索引不需要被检索了,那么应该从索引中将该文档删除。在Lucene中通过IndexReader和indexModifier两个类从索引中删除文档。

1、使用IndexReader删除

IndexReader删除文档需要根据文档的序号进行删除

import java.io.File;import java.io.IOException;import org.apache.lucene.document.Document;import org.apache.lucene.document.Field;import org.apache.lucene.index.CorruptIndexException;import org.apache.lucene.index.IndexReader;import org.apache.lucene.store.Directory;import org.apache.lucene.store.SimpleFSDirectory;public class deleteIndex1 { public static void main(String[] args) { File indexDir = new File("E://Index"); try { Directory dir = new SimpleFSDirectory(indexDir); IndexReader ir= IndexReader.open(dir,false);//第二个参数设置的是否只读,默认是true ir.deleteDocument(8); System.out.println(ir.numDeletedDocs()); //判断是否删除成功 ir.close();//删除后要关闭,否则删除无效 } catch (CorruptIndexException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
这个时候,文档并没有被真正删除,只是做了已经被删除的标记,从而使之不能参与检索,通过调用undeleteAll()方法可以将删除的文档都恢复过来。

使用IndexWriter的optimize()方法可以对做了删除标记的索引进行物理删除,都很简单,不举例。

使用IndexReader.deleteDocuments(new Term("bookname","女"))可以按照词条批量删除索引,不举例

三、更新索引中的文档

无非先删除再添加而已

四、索引的同步

1、lucene并发访问规则:

lucene是被设计用于web环境的,所建立的搜索引擎会不止被一个线程访问,因此需要考虑了并发访问的问题,并发访问的问题如果处理不好会导致索引文件的损坏,为了避免

类似问题,需要谨记以下规则:

1)、任意数量的只读操作都可以同时进行

2)、在某一时刻,只允许一个修改索引的操作。也就是说在同一时间一个索引只能被一个IndexWriter或者IndexReader对象打开。

3)、只读操作可以在索引被修改的情况下进行,并且也可以是并发只读。

2、索引锁机制

为了处理索引同步的问题,Lucene内置了一种锁机制。锁,体现为一种文件。

锁有两种:write.lock 和 commit.lock .

write.lock用于阻止进程同时修改一个索引。对于IndexWriter和IndexReader两个类,在他们进行索引的添加、修改和删除操作的时候,write.lock文件就产生了。这时候如果

有人想修改索引是做不到的。必须要等到close()之后才可以。这两个类调用close()后索文件write.lock也就消失了。

在读取和合并索引块的时候,会用到commit.lock锁,这是一个事物锁。例如,在优化索引的时候,需要先将所有的索引块合并起来,等合并成功之时,再将原先分散的索引块

删除,整个过程任何一步出现问题都会导致索引优化失败,因此要用到事物锁。

这两种锁都是操作索引Lucene自动建立的,不需要手动建立和修改。







分享给朋友:
您可能感兴趣的文章:
随机阅读: