Lucene - 删除文档操作

  • 简述

    删除文档是索引过程的另一个重要操作。当已经索引的内容被更新而索引变得无效或索引变得非常大时使用此操作,然后为了减小大小并更新索引,执行删除操作。
    我们将包含Field(s) 的Document(s)删除到IndexWriter,其中 IndexWriter 用于更新索引。
    现在,我们将向您展示一个逐步的方法,并通过一个基本示例让您了解如何删除文档。
  • 从索引中删除文档

    按照以下步骤从索引中删除文档 -
    Step 1 − 创建一种删除过时文本文件的 Lucene 文档的方法。
    
    private void deleteDocument(File file) throws IOException {
       
       //delete indexes for a file
       writer.deleteDocument(new Term(LuceneConstants.FILE_NAME,file.getName())); 
       writer.commit();
       System.out.println("index contains deleted files: "+writer.hasDeletions());
       System.out.println("index contains documents: "+writer.maxDoc());
       System.out.println("index contains deleted documents: "+writer.numDoc());
    }   
    
  • 创建一个索引写入器

    IndexWriter 类充当在索引过程中创建/更新索引的核心组件。
    按照以下步骤创建一个 IndexWriter -
    Step 1 − 创建IndexWriter 对象。
    Step 2 − 创建一个 Lucene 目录,该目录应指向要存储索引的位置。
    Step 3 - 初始化使用索引目录创建的 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);
    }
    
  • 删除文档并开始重新索引过程

    以下是删除文档的方法。
    • deleteDocuments(Term) − 删除所有包含该词的文档。
    • deleteDocuments(Term[]) − 删除包含数组中任何项的所有文档。
    • deleteDocuments(Query) − 删除与查询匹配的所有文档。
    • deleteDocuments(Query[]) − 删除数组中与查询匹配的所有文档。
    • deleteAll − 删除所有文件。
    
    private void indexFile(File file) throws IOException {
       System.out.println("Deleting index for "+file.getCanonicalPath());
       deleteDocument(file);   
    }
    
  • 示例应用

    为了测试索引过程,让我们创建一个 Lucene 应用程序测试。
    步骤 描述
    1
    创建一个名称的项目LuceneFirstApplication一个包下com.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.index.Term;
    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 deleteDocument(File file) throws IOException {
          //delete indexes for a file
          writer.deleteDocuments(
             new Term(LuceneConstants.FILE_NAME,file.getName())); 
           writer.commit();  
       }  
       private void indexFile(File file) throws IOException {
          System.out.println("Deleting index: "+file.getCanonicalPath());
          deleteDocument(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 中提供的运行选项或使用 Ctrl + F11 编译并运行你的 LuceneTester应用。如果您的应用程序成功运行,它将在 Eclipse IDE 的控制台中打印以下消息 -
    
    Deleting index E:\Lucene\Data\record1.txt
    Deleting index E:\Lucene\Data\record10.txt
    Deleting index E:\Lucene\Data\record2.txt
    Deleting index E:\Lucene\Data\record3.txt
    Deleting index E:\Lucene\Data\record4.txt
    Deleting index E:\Lucene\Data\record5.txt
    Deleting index E:\Lucene\Data\record6.txt
    Deleting index E:\Lucene\Data\record7.txt
    Deleting index E:\Lucene\Data\record8.txt
    Deleting index E:\Lucene\Data\record9.txt
    10 File indexed, time taken: 109 ms
    
    成功运行程序后,您将在您的 index directory
    Lucene 索引目录