2016-09-02 67 views
0

目前我能夠將文檔列表以及單個文檔添加到apache lucene索引中。但我更新索引文件時遇到問題:如何刪除或更新apache Lucene中的文檔

我的方法是一旦文件上傳,所以在寫入磁盤之前,我檢查文件是否存在於驅動器/文件夾中,並刪除基於索引在文件名上。

其次,我將上傳的文件添加到Lucene索引中。

但我遇到的問題是新添加以及舊文檔都顯示在不同的內容搜索結果。

對於例如:文件名Sample_One.txt文本:

這是第一次示範文本。

從索引中刪除上述文件,然後將新的文件內容添加到索引中。

現在的文件內容與相同的文件名其他文本更新:

這是更新的內容的示例文本。

雖然搜索像「樣本」一些文本,結果顯示Sample_One.txt與舊的和新的內容文件兩次。

我想知道我是否缺少一些東西以及如何將文檔更新/刪除到索引中。

代碼片段:

//Deleting the Document from the Index 
public void deleteDocumentsFromIndexUsingTerm(Document doc) throws IOException, ParseException { 
    Term fileTerm = new Term("file_name",doc.get("file_name")); 
    Term contentTerm = new Term("content", doc.get("content")); 
    Term docIDTerm = new Term("document_id", doc.get("document_id")); 

    File indexDir = new File(INDEX_DIRECTORY); 

    Directory directory = FSDirectory.open(indexDir.toPath()); 

    Analyzer analyzer = new StandardAnalyzer(); 
    IndexWriterConfig conf = new IndexWriterConfig(analyzer); 
    IndexWriter indexWriter = new IndexWriter(directory, conf); 

    System.out.println("Deleting the term with - "+doc.get("file_name")); 
    System.out.println("Deleting the term with contents - "+doc.get("content")); 

    indexWriter.deleteDocuments(fileTerm); 
    indexWriter.deleteDocuments(contentTerm); 
    indexWriter.deleteDocuments(docIDTerm); 
    indexWriter.commit(); 
    indexWriter.close(); 
} 

//代碼段文件添加到索引

final String INDEX_DIRECTORY = "D:\\Development\\Lucene_Indexer"; 
    long startTime = System.currentTimeMillis(); 
    List<ContentHandler> contentHandlerList = new ArrayList<ContentHandler>(); 

    String fileNames = (String)request.getAttribute("message"); 

    File file = new File("D:\\Development\\Resume_Sample\\"+fileNames); 

    ArrayList<File> fileList = new ArrayList<File>(); 
    fileList.add(file); 

    Metadata metadata = new Metadata(); 

    // BodyContentHandler set the value as -1 to evade the Text Limit Exception 
    ContentHandler handler = new BodyContentHandler(-1); 
    ParseContext context = new ParseContext(); 
    Parser parser = new AutoDetectParser(); 
    InputStream stream = new FileInputStream(file); 

    try { 
     parser.parse(stream, handler, metadata, context); 
     contentHandlerList.add(handler); 
    }catch (TikaException e) { 
     e.printStackTrace(); 
    }catch (SAXException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    finally { 
     try { 
      stream.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    FieldType fieldType = new FieldType(); 
    fieldType.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS); 
    fieldType.setStoreTermVectors(true); 
    fieldType.setStoreTermVectorPositions(true); 
    fieldType.setStoreTermVectorPayloads(true); 
    fieldType.setStoreTermVectorOffsets(true); 
    fieldType.setStored(true); 


    Analyzer analyzer = new StandardAnalyzer(); 
    Directory directory = FSDirectory.open(new File(INDEX_DIRECTORY).toPath()); 
    IndexWriterConfig conf = new IndexWriterConfig(analyzer); 
    IndexWriter writer = new IndexWriter(directory, conf); 

    Iterator<ContentHandler> handlerIterator = contentHandlerList.iterator(); 
    Iterator<File> fileIterator = fileList.iterator(); 

while (handlerIterator.hasNext() && fileIterator.hasNext()) { 
    Document doc = new Document(); 

    String text = handlerIterator.next().toString(); 
    String textFileName = fileIterator.next().getName(); 

    String idOne = UUID.randomUUID().toString(); 

    Field idField = new Field("document_id",idOne,fieldType); 
    Field fileNameField = new Field("file_name", textFileName, fieldType); 
    Field contentField = new Field("content",text,fieldType); 


    doc.add(idField); 
    doc.add(contentField); 
    doc.add(fileNameField); 

    writer.addDocument(doc); 

    analyzer.close(); 
} 

writer.commit(); 
writer.deleteUnusedFiles(); 
long endTime = System.currentTimeMillis(); 

writer.close(); 

以上首先我儘快刪除文檔文件上傳,然後索引更新的文檔。

回答

1

問題是您的字段在索引時正在分析,但您嘗試刪除的術語是而非分析過。

最好的解決方案是將你想要使用的字段作爲標識符用於此目的StringField,這將導致它被索引而不進行分析。如:

Field idField = new StringField("document_id", idOne); 
doc.add(idField); 

或者,你可以使用IndexWriter.deleteDocuments(Query...),並通過在分析查詢(由QueryParser的產生),但在這種情況下,你應該注意不要刪除比你預期的要更多的文件(任何查詢發現的文檔將被刪除,而不僅僅是最好的結果)。

+0

它工作得很漂亮。你的建議對我來說第二次超過了很多。 – anand

+0

嗨,你可以請幫助我在lucene的AutoSuggestion上的另一個話題。問題stackoverflow鏈接是:http:// stackoverflow。COM /問題/ 39320279 /自動建議 - 不工作,在-的Lucene後優先搜索迭代 – anand