刪除文檔是另一個(gè)重要的操作,索引處理的一部分。此操作用于當(dāng)已經(jīng)索引內(nèi)容被更新和索引變得無(wú)效或索引變得尺寸非常大,那么為了減少尺寸和更新索引,可以使用刪除操作執(zhí)行。
我們刪除文檔包含字段到IndexWriter,IndexWriter用于更新索引。
現(xiàn)在,我們將展示一個(gè)循序漸進(jìn)的過(guò)程,獲得一個(gè)任意文檔來(lái)刪除,通過(guò)一個(gè)基本的例子。
創(chuàng)建到刪除過(guò)時(shí)的文本,使用 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 類(lèi)作為它在索引過(guò)程中創(chuàng)建/更新索引的核心組成部分。
創(chuàng)建IndexWriter的對(duì)象。
創(chuàng)建其應(yīng)指向位置,其中索引是存儲(chǔ)一個(gè) lucene 目錄。
初始化索引目錄,有標(biāo)準(zhǔn)的分析版本信息和其他所需/可選參數(shù)創(chuàng)建 IndexWricrter 對(duì)象。
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); }
下面兩個(gè)是刪除文檔的方式。
deleteDocuments(Term) - 刪除所有包含這個(gè)詞條的文件。
deleteDocuments(Term[]) - 刪除全部包含任何陣列中的詞條的文檔。
deleteDocuments(Query) - 刪除所有與查詢(xún)匹配的文檔。
deleteDocuments(Query[]) - 刪除所有匹配陣列中的查詢(xún)的文檔。
deleteAll - 刪除所有文件。
private void indexFile(File file) throws IOException{ System.out.println("Deleting index for "+file.getCanonicalPath()); deleteDocument(file); }
讓我們創(chuàng)建一個(gè)測(cè)試Lucene的應(yīng)用程序來(lái)測(cè)試索引處理。
步驟 | 描述 |
---|---|
1 | 創(chuàng)建一個(gè)LuceneFirstApplication在包packagecom.yiibai.lucene下。也可以使用EJB創(chuàng)建的項(xiàng)目 |
2 | 創(chuàng)建LuceneConstants.java,TextFileFilter.java和Indexer.java。保持其它的文件不變 |
3 | 創(chuàng)建LuceneTester.java 如下所述 |
4 | 清理和構(gòu)建應(yīng)用程序,以確保業(yè)務(wù)邏輯按要求工作 |
LuceneConstants.java
這個(gè)類(lèi)是用來(lái)提供可應(yīng)用于示例應(yīng)用程序中使用的各種常量。
package com.yiibai.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
此類(lèi)用于 .txt 文件過(guò)濾器
package com.yiibai.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
這個(gè)類(lèi)是用于索引的原始數(shù)據(jù),這樣我們就可以使用Lucene庫(kù),使其可搜索。
package com.yiibai.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
這個(gè)類(lèi)是用來(lái)測(cè)試的Lucene庫(kù)的索引能力
package com.yiibai.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(); } }
使用10個(gè)文件從 record1.txt 到 record10.txt 的文本文件包含簡(jiǎn)單的名稱(chēng)以及學(xué)生的其他細(xì)節(jié),并把它們放在目錄 E:LuceneData。這些數(shù)據(jù)用于測(cè)試。索引目錄路徑應(yīng)創(chuàng)建為E:LuceneIndex。運(yùn)行此程序后,就可以看到該文件夾中創(chuàng)建的索引文件的列表。
一旦創(chuàng)建源,創(chuàng)造了原始數(shù)據(jù),數(shù)據(jù)目錄和索引目錄來(lái)完成,準(zhǔn)備好這一步是編譯和運(yùn)行程序。要做到這一點(diǎn),在LuceneTester.Java文件選項(xiàng)卡中使用Eclipse IDE 的Run選項(xiàng),或使用Ctrl+ F11來(lái)編譯和運(yùn)行應(yīng)用程序LuceneTester。如果應(yīng)用程序一切正常,將在Eclipse IDE控制臺(tái)打印以下消息:
Deleting index E:LuceneDataecord1.txt Deleting index E:LuceneDataecord10.txt Deleting index E:LuceneDataecord2.txt Deleting index E:LuceneDataecord3.txt Deleting index E:LuceneDataecord4.txt Deleting index E:LuceneDataecord5.txt Deleting index E:LuceneDataecord6.txt Deleting index E:LuceneDataecord7.txt Deleting index E:LuceneDataecord8.txt Deleting index E:LuceneDataecord9.txt 10 File indexed, time taken: 109 ms
一旦成功地運(yùn)行程序,將有以下的索引目錄中的內(nèi)容: