Apache Lucene - Indexação de arquivos pdf

2 respostas
E

Boa tarde pessoas,

Alguém que já tenha utilizado o apache lucene para indexação de documentos?
Estou fazendo alguns testes aqui, e ainda estou no início, apenas lendo o pdf e retornando em String seu conteúdo.
Estou usando um exemplo de um blog, e lá diz que não se pode indexar o documento em si com o framework, apenas texto.
Alguém sabe se isso procede?
Preciso indexar algumas páginas de um pdf, mas ele é um manuscrito escaneado em pdf, então não posso retornar o texto (já tentei utilizar o Tesseract OCR, mas ele não reconhece praticamente nada).

Alguma ideia de como resolver isso, alguma pista, sugestão de outro Framework ou qualquer coisa?

Desde já agradeço.

Abraços.

2 Respostas

E

Ah, tô usando o Lucene.

E

Estou conseguindo fazer a indexação, mas a consulta não retorna nada.

Seguem as classes:

package teste;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.text.SimpleDateFormat;

import org.apache.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.SimpleFSDirectory;
import org.apache.lucene.util.Version;
import org.apache.tika.Tika;

public class Indexador {

    private static Logger logger = Logger.getLogger(Indexador.class);
    // {1}
     private String diretorioDosIndices = System.getProperty("user.home")
            + "\\Documents\\NetBeansProjects\\lucene\\indices";
    // {2}
    private String diretorioDosArquivos = System.getProperty("user.home")
            + "\\Documents\\NetBeansProjects\\lucene\\arquivos";
    // {3}
    private IndexWriter writer;
    // {4}
    private Tika tika;

    public static void main(String[] args) {
        Indexador indexador = new Indexador();
        indexador.indexaArquivosDoDiretorio();
    }

    public void indexaArquivosDoDiretorio() {
        try {
            File diretorio = new File(diretorioDosIndices);
            apagaIndices(diretorio);
            // {5}
            Directory d = new SimpleFSDirectory(diretorio);
            logger.info("Diretorio do indice: " + diretorioDosIndices);
            // {6}
            Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_47);
            // {7}
            IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_47,
                    analyzer);
            // {8}
            writer = new IndexWriter(d, config);
            long inicio = System.currentTimeMillis();
            indexaArquivosDoDiretorio(new File(diretorioDosArquivos));
            // {12}
            writer.commit();
            writer.close();
            long fim = System.currentTimeMillis();
            logger.info("Tempo para indexar: " + ((fim - inicio) / 1000) + "s");
        } catch (IOException e) {
            logger.error(e);
        }
    }

    private void apagaIndices(File diretorio) {
        if (diretorio.exists()) {
            File arquivos[] = diretorio.listFiles();
            for (File arquivo : arquivos) {
                arquivo.delete();
            }
        }
    }

    public void indexaArquivosDoDiretorio(File raiz) {
        FilenameFilter filtro = new FilenameFilter() {
            public boolean accept(File arquivo, String nome) {
                if (nome.toLowerCase().endsWith(".pdf")
                        || nome.toLowerCase().endsWith(".odt")
                        || nome.toLowerCase().endsWith(".doc")
                        || nome.toLowerCase().endsWith(".docx")
                        || nome.toLowerCase().endsWith(".ppt")
                        || nome.toLowerCase().endsWith(".pptx")
                        || nome.toLowerCase().endsWith(".xls")
                        || nome.toLowerCase().endsWith(".txt")
                        || nome.toLowerCase().endsWith(".rtf")) {
                    return true;
                }
                return false;
            }
        };
        for (File arquivo : raiz.listFiles(filtro)) {
            if (arquivo.isFile()) {
                StringBuffer msg = new StringBuffer();
                msg.append("Indexando o arquivo ");
                msg.append(arquivo.getAbsoluteFile());
                msg.append(", ");
                msg.append(arquivo.length() / 1000);
                msg.append("kb");
                logger.info(msg);
                try {
                    // {9}
                    String textoExtraido = getTika().parseToString(arquivo);
                    indexaArquivo(arquivo, textoExtraido);
                } catch (Exception e) {
                    logger.error(e);
                }
            } else {
                indexaArquivosDoDiretorio(arquivo);
            }
        }
    }

    private void indexaArquivo(File arquivo, String textoExtraido) {
        SimpleDateFormat formatador = new SimpleDateFormat("yyyyMMdd");
        String ultimaModificacao = formatador.format(arquivo.lastModified());
        // {10}
        Document documento = new Document();
        documento.add(new TextField("UltimaModificacao", ultimaModificacao,
                Store.YES));
        documento.add(new TextField("Caminho", arquivo.getAbsolutePath(),
                Store.YES));
        documento.add(new TextField("Texto", textoExtraido, Store.YES));
        try {
            // {11}
            getWriter().addDocument(documento);
        } catch (IOException e) {
            logger.error(e);
        }
    }

    public Tika getTika() {
        if (tika == null) {
            tika = new Tika();
        }
        return tika;
    }

    public IndexWriter getWriter() {
        return writer;
    }
}
package teste;

import java.io.File;

import javax.swing.JOptionPane;

import org.apache.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.SimpleFSDirectory;
import org.apache.lucene.util.Version;

public class Buscador {
    private static Logger logger = Logger.getLogger(Buscador.class);
    private String diretorioDoIndice = System.getProperty("user.home")
            + "\\Documents\\NetBeansProjects\\lucene\\indices";

    public void buscaComParser(String parametro) {
    try {
        Directory diretorio = new SimpleFSDirectory(new File(
                diretorioDoIndice));
        // {1}
        IndexReader leitor = DirectoryReader.open(diretorio);
        // {2}
        IndexSearcher buscador = new IndexSearcher(leitor);
        Analyzer analisador = new StandardAnalyzer(Version.LUCENE_47);
        // {3}
        QueryParser parser = new QueryParser(Version.LUCENE_47, "Texto",
                analisador);
        Query consulta = parser.parse(parametro);
        long inicio = System.currentTimeMillis();
        // {4}
        TopDocs resultado = buscador.search(consulta, 100);
        long fim = System.currentTimeMillis();
        int totalDeOcorrencias = resultado.totalHits;
        logger.info("Total de documentos encontrados:" + totalDeOcorrencias);
        logger.info("Tempo total para busca: " + (fim - inicio) + "ms");
        // {5}
        for (ScoreDoc sd : resultado.scoreDocs) {
            Document documento = buscador.doc(sd.doc);
            logger.info("Caminho:" + documento.get("Caminho"));
            logger.info("Ultima modificacao:"
                    + documento.get("UltimaModificacao"));
            logger.info("Score:" + sd.score);
            logger.info("--------");
        }
        leitor.close();
    } catch (Exception e) {
        logger.error(e);
    }
    }

    public static void main(String[] args) {
    Buscador b = new Buscador();
    String parametro = JOptionPane.showInputDialog("Consulta");
    b.buscaComParser(parametro);
    }
}

Estou usando a versão 4.9 do Lucene.
Na pasta "arquivos" está meu pdf, e na pasta "indices" estão os indices que são criados pela classe Indexador.
Porém, ao digitar qualquer palavra que esteja no pdf no JOptionPane, não retorna nada - nem erro algum.

Alguem pode dar uma luz?

Criado 25 de novembro de 2014
Ultima resposta 25 de nov. de 2014
Respostas 2
Participantes 1