无法索引和查找文件[Java,Lucene,Tika,Log4j]

时间:2014-03-18 02:19:43

标签: java lucene

我试图在Lucene的帮助下使用java生成索引文件。 我从iMasters开始遵循本指南,并尝试适应4.7.0版本,问题是在某些时候搜索无效。 我检查了文件索引和两个文件中的信息,因为它的内容正在编制索引。 你们能帮助我吗?

按照我的代码: Indexador.java

package main;

import java.io.*;
import java.text.*;

import org.apache.log4j.*;
import org.apache.lucene.analysis.*;
import org.apache.lucene.analysis.standard.*;
import org.apache.lucene.document.*;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.*;
import org.apache.lucene.store.*;
import org.apache.lucene.util.*;
import org.apache.tika.*;

public class Indexador {
    private static Logger logger = Logger.getLogger(Indexador.class);
    // Diretório que irá guardar o índice;
    private String diretorioDosIndices = "C:\\Users\\strokes"
            + "\\Documents\\indice-lucene";
    // Diretório que contém os documentos que serão indexados;
    private String diretorioParaIndexar = "C:\\Users\\strokes"
            + "\\Downloads";
    // IndexWriter: cria e mantém o índice;
    private IndexWriter writer;
    // Biblioteca que extrai texto de diversos formatos conhecidos;
    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);
            // Directory: representa o diretório do índice;
            Directory d = new SimpleFSDirectory(diretorio);
            logger.info("Diretório do índice: " + diretorioDosIndices);
            // Analyser/StandardAnalyser: fazem o pré-processamento do texto.
            // Existem analisadores inclusive em português;
            Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_47);
            // IndexWriterConfig: configurações para criação do índice. No
            // projeto serão utilizados os valores padrão;
            IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_47,
                    analyzer);
            // Inicializa o IndexWriter para gravação;
            writer = new IndexWriter(d, config);
            long inicio = System.currentTimeMillis();
            indexaArquivosDoDiretorio(new File(diretorioParaIndexar));
            // {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 {
                    // Extrai o conteúdo do arquivo com o Tika;
                    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());
        // Monta um Document para indexação
        // Field.Store.YES: armazena uma cópia do texto no índice, aumentando
        // muito o seu tamanho;
        // Field.Index.ANALYZED: utilizado quando o campo é de texto livre;
        // Field.Index.NOT_ANALYZED: utilizado quando o campo é um ID, data ou
        // númerico.
        Document documento = new Document();
        documento.add(new StringField("UltimaModificacao", ultimaModificacao, Field.Store.YES));
        documento.add(new StringField("Caminho", arquivo.getAbsolutePath(), Field.Store.YES));
        documento.add(new StringField("Texto", textoExtraido, Field.Store.YES));
        try {
            // Adiciona o Document no índice, mas este só estará disponível para
            // consulta após o commit.
            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;
    }
}

Buscador.java

package main;

import java.io.*;

import javax.swing.*;

import org.apache.log4j.*;
import org.apache.lucene.analysis.*;
import org.apache.lucene.analysis.standard.*;
import org.apache.lucene.document.*;
import org.apache.lucene.index.*;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.store.*;
import org.apache.lucene.util.*;

public class Buscador {
    private static Logger logger = Logger.getLogger(Buscador.class);
    private String diretorioDoIndice = "C:\\Users\\strokes"
            + "\\Documents\\indice-lucene";

    public void buscaComParser(String parametro) {
        try {
            Directory diretorio = new SimpleFSDirectory(new File(
                    diretorioDoIndice));
            // IndexReader: classe abstrata responsável por acessar o índice;
            IndexReader leitor = DirectoryReader.open(diretorio);
            // IndexSearcher: implementa os métodos necessários para realizar
            // buscas em um índice;
            IndexSearcher buscador = new IndexSearcher(leitor);
            Analyzer analisador = new StandardAnalyzer(Version.LUCENE_47);
            // QueryParser/Query: representa a consulta do usuário. Outros
            // exemplos de query podem ser vistos no Javadoc;
            QueryParser parser = new QueryParser(Version.LUCENE_47, "Texto",
                    analisador);
            Query consulta = parser.parse(parametro);
            long inicio = System.currentTimeMillis();
            // Realiza a busca e armazena o resultado em um TopDocs;
            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");
            // ScoreDoc: representa cada um dos documentos retornados na busca.
            for (ScoreDoc sd : resultado.scoreDocs) {
                Document documento = buscador.doc(sd.doc);
                logger.info("Caminho:" + documento.get("Caminho"));
                logger.info("Última modificação:"
                        + documento.get("UltimaModificacao"));
                logger.info("Score:" + sd.score);
                logger.info("--------");
            }
        } catch (Exception e) {
            logger.error(e);
        }
    }

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

1 个答案:

答案 0 :(得分:0)

你现场" Texto"是StringField,这意味着它不会被分析,并且它的全部内容将被索引为单个标记。它与Lucene 3.6中的KeywordAnalyzer实际上相同,或者将字段设置为Field.Index.NOT_ANALYZED。在Lucene 4.X中,您应该使用TextField代替,这是文本内容的标准字段,因此会进行分析。