Lucene - 更新文档操作

  • 简述

    作为索引过程的一部分,更新文档是另一个重要的操作。当已经索引的内容被更新并且索引变得无效时使用此操作。此操作也称为重新索引。
    我们将包含Field(s) 的Document(s)更新为 IndexWriter,其中 IndexWriter 用于更新索引。
    我们现在将向您展示一个逐步的方法,并帮助您使用一个基本示例来了解如何更新文档。
  • 将文档更新为索引

    按照此步骤将文档更新为索引 -
    Step 1 - 创建一个方法来从更新的文本文件更新 Lucene 文档。
    
    private void updateDocument(File file) throws IOException {
       Document document = new Document();
       //update indexes for file contents
       writer.updateDocument(new Term 
          (LuceneConstants.CONTENTS, 
          new FileReader(file)),document); 
       writer.close();
    }   
    
  • 创建一个索引写入器

    按照以下步骤创建一个 IndexWriter -
    Step 1 − IndexWriter 类作为核心组件,在索引过程中创建/更新索引。
    Step 2 − 创建IndexWriter 对象。
    Step 3 − 创建一个 Lucene 目录,该目录应指向要存储索引的位置。
    Step 4 - 初始化使用索引目录创建的 IndexWriter 对象,一个具有版本信息和其他必需/可选参数的标准分析器。
    
    private IndexWriter writer;
    public Indexer(String indexDirectoryPath) throws IOException {
       //this directory will contain the indexes
       Directory indexDirectory = 
          FSDirectory.open(new File(indexDirectoryPath));
       
       //create the indexer
       writer = new IndexWriter(indexDirectory, 
          new StandardAnalyzer(Version.LUCENE_36),true,
          IndexWriter.MaxFieldLength.UNLIMITED);
    }
    
  • 更新文档并开始重新索引过程

    以下是更新文档的两种方法。
    • updateDocument(Term, Document) − 删除包含该词条的文档,并使用默认分析器(在创建索引编写器时指定)添加该文档。
    • updateDocument(Term, Document,Analyzer) − 删除包含该术语的文档并使用提供的分析器添加该文档。
    
    private void indexFile(File file) throws IOException {
       System.out.println("Updating index for "+file.getCanonicalPath());
       updateDocument(file);   
    }
    
  • 示例应用

    为了测试索引过程,让我们创建一个 Lucene 应用程序测试。
    描述
    1
    创建一个名称的项目LuceneFirstApplication一个下packagecom.jc2182.lucene作为解释Lucene的-第一个应用程序的章节。您还可以使用在EJB - First Application章节中创建的项目来理解本章的索引过程。
    2
    创建LuceneConstants.java,TextFileFilter.javaIndexer.java作为解释Lucene的-第一个应用程序的章节。保持其余文件不变。
    3
    如下所述创建LuceneTester.java
    4
    清理并构建应用程序以确保业务逻辑按照要求工作。

    LuceneConstants.java

    此类用于提供要在整个示例应用程序中使用的各种常量。
    
    package com.jc2182.lucene;
    public class LuceneConstants {
       public static final String CONTENTS = "contents";
       public static final String FILE_NAME = "filename";
       public static final String FILE_PATH = "filepath";
       public static final int MAX_SEARCH = 10;
    }
    

    TextFileFilter.java

    这个类用作 .txt 文件过滤器。
    
    package com.jc2182.lucene;
    import java.io.File;
    import java.io.FileFilter;
    public class TextFileFilter implements FileFilter {
       @Override
       public boolean accept(File pathname) {
          return pathname.getName().toLowerCase().endsWith(".txt");
       }
    }
    

    Indexer.java

    此类用于索引原始数据,以便我们可以使用 Lucene 库对其进行搜索。
    
    package com.jc2182.lucene;
    import java.io.File;
    import java.io.FileFilter;
    import java.io.FileReader;
    import java.io.IOException;
    import org.apache.lucene.analysis.standard.StandardAnalyzer;
    import org.apache.lucene.document.Document;
    import org.apache.lucene.document.Field;
    import org.apache.lucene.index.CorruptIndexException;
    import org.apache.lucene.index.IndexWriter;
    import org.apache.lucene.store.Directory;
    import org.apache.lucene.store.FSDirectory;
    import org.apache.lucene.util.Version;
    public class Indexer {
       private IndexWriter writer;
       public Indexer(String indexDirectoryPath) throws IOException {
          //this directory will contain the indexes
          Directory indexDirectory = 
             FSDirectory.open(new File(indexDirectoryPath));
          //create the indexer
          writer = new IndexWriter(indexDirectory, 
             new StandardAnalyzer(Version.LUCENE_36),true,
             IndexWriter.MaxFieldLength.UNLIMITED);
       }
       public void close() throws CorruptIndexException, IOException {
          writer.close();
       }
       private void updateDocument(File file) throws IOException {
          Document document = new Document();
          //update indexes for file contents
          writer.updateDocument(
             new Term(LuceneConstants.FILE_NAME,
             file.getName()),document); 
          writer.close();
       }  
       private void indexFile(File file) throws IOException {
          System.out.println("Updating index: "+file.getCanonicalPath());
          updateDocument(file);      
       }
       public int createIndex(String dataDirPath, FileFilter filter) 
          throws IOException {
          //get all files in the data directory
          File[] files = new File(dataDirPath).listFiles();
          for (File file : files) {
             if(!file.isDirectory()
                && !file.isHidden()
                && file.exists()
                && file.canRead()
                && filter.accept(file)
             ){
                indexFile(file);
             }
          }
          return writer.numDocs();
       }
    }
    

    LuceneTester.java

    该类用于测试 Lucene 库的索引能力。
    
    package com.jc2182.lucene;
    import java.io.IOException;
    public class LuceneTester {
       
       String indexDir = "E:\\Lucene\\Index";
       String dataDir = "E:\\Lucene\\Data";
       Indexer indexer;
       
       public static void main(String[] args) {
          LuceneTester tester;
          try {
             tester = new LuceneTester();
             tester.createIndex();
          } catch (IOException e) {
             e.printStackTrace();
          } 
       }
       private void createIndex() throws IOException {
          indexer = new Indexer(indexDir);
          int numIndexed;
          long startTime = System.currentTimeMillis(); 
          numIndexed = indexer.createIndex(dataDir, new TextFileFilter());
          long endTime = System.currentTimeMillis();
          indexer.close();
       }
    }
    
  • 数据和索引目录创建

    我们使用了从 record1.txt 到 record10.txt 的 10 个文本文件,其中包含学生的姓名和其他详细信息,并将它们放在目录中 E:\Lucene\Data. 运行 E:\Lucene\Index. 程序后,您可以看到在该文件夹中创建的索引文件列表
  • 运行程序

    完成源、原始数据、数据目录和索引目录的创建后,您可以继续编译和运行程序。 为此,请保持 LuceneTester.Java 文件选项卡处于活动状态并使用 Eclipse IDE 中提供的 Run 选项或使用 Ctrl + F11 编译并运行您的 LuceneTester 应用程序。 如果您的应用程序成功运行,它将在 Eclipse IDE 的控制台中打印以下消息 -
    
    Indexing E:\Lucene\Data\record1.txt
    Indexing E:\Lucene\Data\record10.txt
    Indexing E:\Lucene\Data\record2.txt
    Indexing E:\Lucene\Data\record3.txt
    Indexing E:\Lucene\Data\record4.txt
    Indexing E:\Lucene\Data\record5.txt
    Indexing E:\Lucene\Data\record6.txt
    Indexing E:\Lucene\Data\record7.txt
    Indexing E:\Lucene\Data\record8.txt
    Indexing E:\Lucene\Data\record9.txt
    10 File indexed, time taken: 109 ms
    
    成功运行程序后,您将拥有以下内容 索引目录−
    Lucene Index Directory