2017-08-25 84 views
1

我想從使用Apache Tika的PDF文件中提取文本內容,然後將數據傳遞給Lucene進行索引。 )爲Lucene索引提取PDF文本的有效方法

public static String extract(File file) throws IOException, SAXException, TikaException { 

     InputStream input = new FileInputStream(file); 
     ContentHandler handler = new BodyContentHandler(-1); 
     Metadata metadata = new Metadata(); 
     new PDFParser().parse(input, handler, metadata, new ParseContext()); 
     String plainText = handler.toString(); 
     input.close(); 
     return plainText; 
    } 

我查詢相關的呼叫

handler.toString(;

現在我們使用多個線程(4到8,可由用戶配置)執行提取過程。那麼是否有其他方法可以獲得我們可以用於索引目的的Lucene的流。原因是我感到巨大的絃樂會推動更大的堆。

目前,如果完成的指標爲:

doc.add(new TextField(fieldName, ExtractPdf.extract(file), Field.Store.NO)); 

我們需要從50KB提取和指數約500K不同大小的文件,50MB。

回答

1

我以前沒有在Apache Tika上工作過,但你的問題很有意思,所以我環視了一下&我沒有看到致電toString()是造成問題的根本原因。

按我的理解 - 效率可以通過判斷來實現,如果你總是需要FULL正文不論任何大小的文本中的程序邏輯可以工作正常,如果你只檢索的N A分體-LENGTH

我比相信你會永遠需要全身的文字和你的程序將無法與偏身工作,讓所有可以實現(假設你總是需要全文)的效率更是打破大型字符串如here所示 - 使用自定義內容處理器修飾器以塊流式傳輸純文本。所以內存明智的,你的程序應該仍然能夠保存這麼大的身體,但你的身體被分成這可能會簡化你的索引的下游過程塊。

你的程序應該列出它的內存要求爲每個文件最大支持,使用這種方法,你不會得到一種解脫那裏。所以很早就決定要處理多大的文件。

其他選項似乎發展,你在增量方式解析相同的文件多次一個過程,不會是非常有效的是(只是建議作爲一種可能的方法,不知道是否可行在Tika)。

唉唉....冗長的寫了:)

具有高於點說,你還應該注意的是你應該嘗試分離文件解析&指數的步驟,所以你可以給每個步驟提供不同的調整和配置。使用一個線程安全的阻塞隊列的消費模式,或者你可能會Spring Batch API去 -

要麼你可以編寫一個典型的生產商。

隨着春天批次,您的讀者將負責讀取&解析文件,讀者會把字符串的清單處理器,然後字符串名單的列表會去的作家和作家也根本指數根據您的塊大小配置批量文件。

解耦是強制性的,因爲您應該注意到Lucene IndexWriter是一個線程安全的類,除了在文件解析級別使用多線程外,還可以使用多個線程來執行更快的索引。

希望它有幫助!

而且,請注意,在Java中的字符串是垃圾收集像使用普通的對象,如果它不是拘留,see

+0

感謝詳細的解答。假設我需要索引或解析文件的全部內容,這是正確的。我也實現了線程來加快速度。我需要檢查塊選項,因爲這看起來很有趣。 GC正在觸發並正在執行清理,但我的實際意圖是減少堆使用中的尖峯數量。在測試場景下,我的堆使用率高達1 GB,但在所有索引過程完成後,實際使用量可能爲20 MB。我會檢查塊的方法並確認。如果解決,將標記爲答案 – Soumya