Uma pesquisa simples de arquivos com Lucene
1. Visão geral
O Apache Lucene é um mecanismo de pesquisa de texto completo, que pode ser usado por várias linguagens de programação. Para começar a usar o Lucene, consulte nossoarticle here introdutório.
Neste artigo rápido, indexaremos um arquivo de texto e pesquisaremosStringse trechos de texto dentro desse arquivo.
2. Configuração do Maven
3. Diretório do sistema de arquivos
Para indexar arquivos, primeiro precisamos criar um índice do sistema de arquivos.
Lucene fornece a classeFSDirectory para criar um índice do sistema de arquivos:
Directory directory = FSDirectory.open(Paths.get(indexPath));
Aqui,indexPath é a localização do diretório. If the directory doesn’t exist, Lucene will create it.
Lucene fornece três implementações concretas da classe abstrataFSDirectory:SimpleFSDirectory, NIOFSDirectory, and MMapDirectory. Cada uma delas pode ter problemas especiais com um determinado ambiente.
Por exemplo,SimpleFSDirectory has poor concurrent performance as it blocks when multiple threads read from the same file.
Da mesma forma, oNIOFSDirectory and MMapDirectory implementations face file-channel issues in Windows and memory release problems respectively.
To overcome such environment peculiarities Lucene provides the FSDirectory.open() method. Quando chamado, tenta escolher a melhor implementação dependendo do ambiente.
4. Arquivo de Texto de Índice
Depois de criar o diretório de índice, vamos prosseguir e adicionar um arquivo ao índice:
public void addFileToIndex(String filepath) {
Path path = Paths.get(filepath);
File file = path.toFile();
IndexWriterConfig indexWriterConfig
= new IndexWriterConfig(analyzer);
Directory indexDirectory = FSDirectory
.open(Paths.get(indexPath));
IndexWriter indexWriter = new IndexWriter(
indexDirectory, indexWriterConfig);
Document document = new Document();
FileReader fileReader = new FileReader(file);
document.add(
new TextField("contents", fileReader));
document.add(
new StringField("path", file.getPath(), Field.Store.YES));
document.add(
new StringField("filename", file.getName(), Field.Store.YES));
indexWriter.addDocument(document);
indexWriter.close();
}
Aqui, criamos um documento com doisStringFields chamados “caminho” e “nome do arquivo” e umTextField chamado “conteúdo”.
Observe que passamos a instânciafileReader como o segundo parâmetro paraTextField. O documento é adicionado ao índice usando oIndexWriter.
O terceiro argumento no construtorTextField ouStringField indica se o valor do campo também será armazenado.
Finalmente, invocamosclose() deIndexWriter para fechar e liberar o bloqueio dos arquivos de índice.
5. Pesquisar arquivos indexados
Agora vamos pesquisar os arquivos que indexamos:
public List searchFiles(String inField, String queryString) {
Query query = new QueryParser(inField, analyzer)
.parse(queryString);
Directory indexDirectory = FSDirectory
.open(Paths.get(indexPath));
IndexReader indexReader = DirectoryReader
.open(indexDirectory);
IndexSearcher searcher = new IndexSearcher(indexReader);
TopDocs topDocs = searcher.search(query, 10);
return topDocs.scoreDocs.stream()
.map(scoreDoc -> searcher.doc(scoreDoc.doc))
.collect(Collectors.toList());
}
Vamos agora testar a funcionalidade:
@Test
public void givenSearchQueryWhenFetchedFileNamehenCorrect(){
String indexPath = "/tmp/index";
String dataPath = "/tmp/data/file1.txt";
Directory directory = FSDirectory
.open(Paths.get(indexPath));
LuceneFileSearch luceneFileSearch
= new LuceneFileSearch(directory, new StandardAnalyzer());
luceneFileSearch.addFileToIndex(dataPath);
List docs = luceneFileSearch
.searchFiles("contents", "consectetur");
assertEquals("file1.txt", docs.get(0).get("filename"));
}
Observe como estamos criando um índice do sistema de arquivos no localindexPathe indexando ofile1.txt.
Em seguida, simplesmente procuramosString “consectetur” no campo“contents”.
6. Conclusão
Este artigo foi uma rápida demonstração da indexação e pesquisa de texto com o Apache Lucene. Para saber mais sobre indexação, searing e consultas do Lucene, consulte nossointroduction to Lucene article.
Como sempre, o código dos exemplos pode ser encontradoover on Github.