从Lucene索引中提取PDF文本的有效方法

时间:2017-08-25 16:22:35

标签: java lucene apache-tika

我正在尝试使用Apache Tika从PDF文件中提取文本内容,然后将数据传递给Lucene进行索引。

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));

我们需要提取和索引大约500K不同大小的文档,从50KB到50MB。

1 个答案:

答案 0 :(得分:1)

我之前没有使用过Apache Tika,但你的问题很有趣所以我环顾四周。我没有看到呼叫toString()是导致问题的根本原因。

根据我的理解 - 效率可以通过决定是否总是需要全身文字来实现,无论文本是否为任何大小 OR ,您的程序逻辑可以正常工作您只检索 N-LENGTH 的部分正文。

我更确定你总是需要完整的正文,你的程序不能使用部分正文,所以你可以实现的所有效率(假设你总是需要全文)就是打破那么大的使用自定义内容处理程序装饰器将字符串分组显示为here下的部分 - 以块的形式流式传输纯文本。因此,在内存方面,您的程序仍然应该能够存储如此庞大的主体,但是您的主体会被分解成块,这可能会简化下游的索引过程。

您的程序应按照支持的最大文件大小列出其内存要求,并且使用此方法您不会在那里得到解脱。所以它很早就决定了你想要处理的大文件。

其他选项似乎开发了一个过程,您可以以递增的方式多次解析同一个文件,并且也不会非常有效(只是建议作为一种可能的方法,不确定Tika是否可行)。

啊......冗长的写作:)

如上所述,您还应该注意,您应该尝试解耦​​文件解析&索引步骤,以便您可以为每个步骤提供不同的调整和配置。

您可以使用线程安全阻塞队列对典型的生产者 - 消费者模式进行编码,也可以使用Spring Batch API

使用Spring批次,您的读者将负责阅读和阅读。解析文件后,读者会将字符串列表传递给处理器,然后字符串列表将转到编写器,编写器将根据批量索引少量文件您的块大小配置。

此处必须使用解耦,因为您应该注意Lucene IndexWriter是一个线程-safe类,除了在文件解析级别使用多线程之外,您还可以使用多个线程来执行更快的索引。

希望它有所帮助!!

另外,请注意,如果没有实例化,Java中的String就像任何普通对象一样被垃圾收集,see