Java Lucene(1):索引操作

来源:互联网 发布:java就业形势 编辑:程序博客网 时间:2024/06/01 15:59

java lucene技术 (1):索引操作

Lucene 可以帮你完成搜索存储在硬盘上的文件、电子邮件、或网页,甚至是数据库中的数据,但是,在进行搜索以前,你必须预先完成对这些数据的索引操作(Indexing)。这正是本节所要讲解的主题。接下来,你将学会如何对数据进行索引。

程序1.1 通过Lucene API 的几个方法完成对数据建立索引的过程:

File FileAddress = new File(“索引路径”);

IndexWriter iw = new IndexWriter(FileAddress,new StandardAnalyzer(),true);

Field field = new Field(“content”, “字串”, Field.Index.Tokenize,Field.Store.Yes);

Document doc = new Document();

Doc.add (field);

iw.addDocument(doc);

iw.close();

以上,Lucene建立索引的一般步骤,在涉及索引的问题上,不仅仅是它的建立,还有索引的删除,更新等等。下边,我将较详细的描述它们的操作原理和步骤:

11索引的删除与更新

Lucene不提供update(Document)方法。为了达到更新的目的,必须首先从一个索引中删除待更新的文档,然后将修改过的文档重新添加到索引中。

程序1.2提供更新索引的过程:

IndexReader reader = IndexReader.open(dir);

reader.delete(newTerm(“city”,“Amsterdam”));

reader.close();

IndexWriterwriter=newIndexWriter(dir,getAnalyzer(),false);

Documentdoc=newDocument();

doc.add(Field.Text(“city”,“Haag”));

        writer.addDocument(doc);

writer.optimize();

writer.close();

但是当数据更新频繁,Lucene不能很好得以增量索引的方式实时更新,对同一个索引文件读写添加。

12 调整索引性能

在一个典型的索引应用中,程序性能的瓶颈存在于将索引文件写入磁盘的过程中。新的Document对象添加到Lucene的索引里时,它们最初将被缓存在内存中,而不是立刻写入磁盘里。这个缓存操作的目的是提高性能;IndexWriter提供了几个变量,用于调节缓存的大小和磁盘写入的频率。

mergeFactor : 控制段的合并频率和大小。

maxMergeDocs : 限制每个段的文档数量。

minMergeDocs : 控制索引时RAM使用的总量。

下面通过一个程序,可以使读者更清晰的了解它们的作用

public class MergeIndex {

 public static void main(String[] args) throws IOException {

   MergeIndex mergeindex = new MergeIndex();

   mergeindex.indexBuild();

   System.out.println("ok");

 }

 public void indexBuild(){

 

  try {

   File index_dir = new File("F:/Test/data");

   if (index_dir.exists()) {

    index_dir.delete();

   }

   IndexWriter writer = new IndexWriter("F:/Test/dbtest",

     new StandardAnalyzer(), true);

   writer.setUseCompoundFile(true);

   writer.mergeFactor = 3;

   writer.maxMergeDocs = 20;

   writer.minMergeDocs = 2;

   indexFile(writer, index_dir);

   writer.close();

  } catch (IOException e) {

   System.out.println(e.getMessage());

  }

 }

 

 

 public static void indexFile(IndexWriter writer, File file)

   throws IOException {

  if (file.canRead()) {

   if (file.isDirectory()) {

    String[] files = file.list();

    if (files != null) {

     for (int i = 0; i < files.length; i++) {

      indexFile(writer, new File(file, files[i]));

     }

    }

   } else {

    try {

     if (file.getName().endsWith(".txt")) {

      writer.addDocument(FileDocument.Document(file));

     }

    }

    catch (FileNotFoundException fnfe) {

     System.out.println(fnfe.getMessage());

    }

   }

  }

 }

}

minMergeDocs是控制多少个document生成一个segementmergeFactor控制几个segment合并的;maxMergeDocs控制一个segment中最多包含多少document.

在路径F:/Test/data下建立3txt文本,分别为01.txt02.txt03.txt,然后运行MergeIndex,在路径F:/Test/dbtest下,生成3个文件:_4.cfsdeletablesegments(关于这些文件,将在以后的文章中给出说明),使用编辑工具打开_4.cfs,会发现它包含了F:/Test/data3txt文件信息,打开segments,发现有’_9’信息,这是因为minMergeDocs = 3 只允许有3个文档文件生成一个segmentsegments文件中包含有目前segment信息。

 

13对索引批处理

一种方式是:可以把RAMDirector作为缓冲器,先将索引文件缓存在缓冲器中,再把数据写入基于FSDirectory的索引中,以达到改善性能的目的。

程序1.3可供读者参考:

  FSDirectory fsd = FSDirectory.getDirectory("F:/Test/dbtest",true);  

  RAMDirectory ramd = new RAMDirectory();

  IndexWriter fsdiw = new IndexWriter(fsd,new StandardAnalyzer(),true);

  IndexWriter ramdiw = new IndexWriter(ramd,new StandardAnalyzer(),true);

  ramdiw.mergeFactor = 3;

       ramdiw.minMergeDocs = 2;

  indexFile (ramdiw,INDEX_DIR);

  Directory[] ramdirectory = {ramd};

  if(ramdiw.docCount()>=6){

         fsdiw.addIndexes(ramdirectory);

         ramdiw.close();

         ramdiw = new IndexWriter(ramd,new StandardAnalyzer(),true);

         fsdiw.close();

  }

 

public static void indexFile(IndexWriter writer, File file)

   throws IOException {

  if (file.canRead()) {

   if (file.isDirectory()) {

    String[] files = file.list();

    if (files != null) {

     for (int i = 0; i < files.length; i++) {

      indexFile(writer, new File(file, files[i]));

     }

    }

   } else {

    try {

     if (file.getName().endsWith(".txt")) {

      writer.addDocument(FileDocument.Document(file));

     }

    }

    catch (FileNotFoundException fnfe) {

     System.out.println(fnfe.getMessage());

    }

   }

  }

 }

  

 

原创粉丝点击