2017-08-25 37 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