关于java:从PDF中为Lucene索引提取文本的有效方法

Efficient way to extract text from PDF for Lucene indexing

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

1
2
3
4
5
6
7
8
9
10
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用于索引目的。 原因是我感觉巨大的弦乐将推动更大的堆积。

目前索引如果完成如下:

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

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


我之前没有参与Apache Tika,但你的问题很有趣所以我环顾四周我没有看到调用toString()是问题的根本原因。

根据我的理解 - 效率可以通过决定你是否总是需要FULL BODY TEXT来实现,无论文本是否具有任何大小,或者如果你只检索N-LENGTH的部分体,你的程序逻辑可以正常工作。

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

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

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

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

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

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

使用Spring批次,您的读者将负责阅读和阅读。在解析文件时,阅读器会将List of String传递给处理器,然后一个List of List将进入编写器,编写器将根据您的块大小配置简单地批量索引少量文件。

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

希望能帮助到你 !!

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