Une recherche de fichiers simple avec Lucene

1. Vue d'ensemble

Apache Lucene est un moteur de recherche en texte intégral, qui peut être utilisé par divers langages de programmation. Pour commencer avec Lucene, veuillez consulter notre article d'introduction ici.

Dans cet article rapide, nous indexerons un fichier texte et rechercherons des exemples de chaînes et d'extraits de texte dans ce fichier.

2. Configuration de Maven

Ajoutons d'abord les dépendances nécessaires:

 org.apache.lucene lucene-core 7.1.0 

La dernière version peut être trouvée ici.

De plus, pour analyser nos requêtes de recherche, nous aurons besoin de:

 org.apache.lucene lucene-queryparser 7.1.0 

N'oubliez pas de vérifier la dernière version ici.

3. Répertoire du système de fichiers

Pour indexer les fichiers, nous devons d'abord créer un index du système de fichiers.

Lucene fournit la classe FSDirectory pour créer un index de système de fichiers:

Directory directory = FSDirectory.open(Paths.get(indexPath));

Ici, indexPath est l'emplacement du répertoire. Si le répertoire n'existe pas, Lucene le créera.

Lucene fournit trois implémentations concrètes de la classe abstraite FSDirectory : SimpleFSDirectory, NIOFSDirectory et MMapDirectory. Chacun d'eux peut avoir des problèmes particuliers avec un environnement donné.

Par exemple, SimpleFSDirectory a de mauvaises performances simultanées car il se bloque lorsque plusieurs threads lisent à partir du même fichier.

De même, les implémentations NIOFSDirectory et MMapDirectory rencontrent respectivement des problèmes de canal de fichier dans Windows et des problèmes de libération de mémoire.

Pour surmonter ces particularités d'environnement, Lucene fournit la méthode FSDirectory.open () . Lorsqu'il est appelé, il essaie de choisir la meilleure implémentation en fonction de l'environnement.

4. Fichier texte d'index

Une fois que nous avons créé le répertoire d'index, allons-y et ajoutons un fichier à l'index:

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

Ici, nous créons un document avec deux StringFields nommés «path» et «filename» et un TextField appelé «contents».

Notez que nous transmettons l' instance fileReader comme deuxième paramètre à TextField . Le document est ajouté à l'index à l'aide d' IndexWriter.

Le troisième argument du constructeur TextField ou StringField indique si la valeur du champ sera également stockée.

Enfin, nous invoquons la fonction close () de l' IndexWriter pour fermer et libérer le verrou des fichiers d'index.

5. Rechercher des fichiers indexés

Maintenant, recherchons les fichiers que nous avons indexés:

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

Testons maintenant la fonctionnalité:

@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")); }

Remarquez comment nous créons un index de système de fichiers dans l'emplacement indexPath et indexons le file1.txt.

Ensuite, nous cherchons simplement la chaîne « consectetur » dans le champ «contenu» .

6. Conclusion

Cet article était une démonstration rapide de l'indexation et de la recherche de texte avec Apache Lucene. Pour en savoir plus sur l'indexation, la saisie et les requêtes de Lucene, veuillez consulter notre article d'introduction à Lucene.

Comme toujours, le code des exemples peut être trouvé sur Github.