Lucene - Szybki przewodnik

Lucene to prosty, ale potężny oparty na Javie Searchbiblioteka. Można go używać w dowolnej aplikacji, aby dodać do niej możliwość wyszukiwania. Lucene to projekt open source. Jest skalowalny. Ta wydajna biblioteka służy do indeksowania i wyszukiwania praktycznie każdego rodzaju tekstu. Biblioteka Lucene zapewnia podstawowe operacje wymagane przez każdą aplikację wyszukującą. Indeksowanie i wyszukiwanie.

Jak działa wyszukiwarka?

Aplikacja wyszukująca wykonuje wszystkie lub kilka z następujących operacji -

Krok Tytuł Opis
1

Acquire Raw Content

Pierwszym krokiem każdej aplikacji wyszukującej jest zebranie docelowej treści, na której ma zostać przeprowadzona wyszukiwarka.

2

Build the document

Następnym krokiem jest zbudowanie dokumentu (ów) z surowej treści, którą aplikacja wyszukująca może łatwo zrozumieć i zinterpretować.

3

Analyze the document

Przed przystąpieniem do indeksowania dokument należy przeanalizować pod kątem tego, która część tekstu jest kandydatem do indeksowania. Na tym procesie dokument jest analizowany.

4

Indexing the document

Po utworzeniu i przeanalizowaniu dokumentów następnym krokiem jest ich indeksowanie, aby można było pobrać ten dokument na podstawie określonych kluczy zamiast całej treści dokumentu. Proces indeksowania jest podobny do indeksów na końcu książki, w których typowe słowa są wyświetlane wraz z numerami stron, dzięki czemu można je szybko śledzić, zamiast przeszukiwać całą książkę.

5

User Interface for Search

Gdy baza danych indeksów jest już gotowa, aplikacja może przeprowadzić dowolne wyszukiwanie. Aby ułatwić użytkownikowi wyszukiwanie, aplikacja musi udostępniać użytkownikaa mean lub a user interface gdzie użytkownik może wprowadzić tekst i rozpocząć proces wyszukiwania.

6

Build Query

Gdy użytkownik zażąda wyszukania tekstu, aplikacja powinna przygotować obiekt Query wykorzystujący ten tekst, który może być użyty do zapytania bazy danych indeksu w celu uzyskania odpowiednich szczegółów.

7

Search Query

Korzystając z obiektu zapytania, baza danych indeksu jest następnie sprawdzana w celu uzyskania odpowiednich szczegółów i dokumentów treści.

8

Render Results

Po otrzymaniu wyniku aplikacja powinna zdecydować, jak pokazać wyniki użytkownikowi za pomocą interfejsu użytkownika. Ile informacji ma zostać wyświetlonych na pierwszy rzut oka i tak dalej.

Oprócz tych podstawowych operacji aplikacja wyszukująca może również udostępniać pliki administration user interfacei pomóc administratorom aplikacji kontrolować poziom wyszukiwania w oparciu o profile użytkowników. Analiza wyników wyszukiwania to kolejny ważny i zaawansowany aspekt każdej aplikacji wyszukującej.

Rola Lucene w wyszukiwarce

Lucene odgrywa rolę we wspomnianych powyżej krokach od 2 do 7 i zapewnia klasy do wykonania wymaganych operacji. Krótko mówiąc, Lucene jest sercem każdej aplikacji wyszukującej i zapewnia kluczowe operacje związane z indeksowaniem i wyszukiwaniem. Pozyskanie zawartości i wyświetlenie wyników pozostawia do obsługi części aplikacji.

W następnym rozdziale przeprowadzimy prostą wyszukiwarkę przy użyciu biblioteki Lucene Search.

Ten samouczek poprowadzi Cię, jak przygotować środowisko programistyczne do rozpoczęcia pracy z Spring Framework. Ten samouczek nauczy Cię również, jak skonfigurować JDK, Tomcat i Eclipse na swoim komputerze przed skonfigurowaniem Spring Framework -

Krok 1 - Instalacja Java Development Kit (JDK)

Najnowszą wersję pakietu SDK można pobrać z witryny Oracle Java: Java SE Downloads . W pobranych plikach znajdziesz instrukcje instalacji JDK; postępuj zgodnie z podanymi instrukcjami, aby zainstalować i skonfigurować ustawienia. Na koniec ustaw zmienne środowiskowe PATH i JAVA_HOME, aby odwoływały się do katalogu zawierającego oprogramowanie Java i javac, zazwyczaj odpowiednio katalog_instalacyjny_java / bin i katalog_instalacyjny_java.

Jeśli używasz systemu Windows i zainstalowałeś zestaw JDK w C: \ jdk1.6.0_15, musisz umieścić następujący wiersz w pliku C: \ autoexec.bat.

set PATH = C:\jdk1.6.0_15\bin;%PATH%
set JAVA_HOME = C:\jdk1.6.0_15

Alternatywnie, w Windows NT / 2000 / XP, możesz także kliknąć prawym przyciskiem myszy My Computer, Wybierz Properties, następnie Advanced, następnie Environment Variables. Następnie zaktualizujPATH wartość i naciśnij OK przycisk.

W systemie Unix (Solaris, Linux itp.), Jeśli SDK jest zainstalowany w /usr/local/jdk1.6.0_15 i używasz powłoki C, umieściłbyś następujące elementy w swoim pliku .cshrc.

setenv PATH /usr/local/jdk1.6.0_15/bin:$PATH
setenv JAVA_HOME /usr/local/jdk1.6.0_15

Alternatywnie, jeśli używasz Integrated Development Environment (IDE) Podobnie jak Borland JBuilder, Eclipse, IntelliJ IDEA lub Sun ONE Studio, skompiluj i uruchom prosty program, aby potwierdzić, że IDE wie, gdzie zainstalowałeś Javę, w przeciwnym razie wykonaj odpowiednią konfigurację zgodnie z dokumentem IDE.

Krok 2 - Konfiguracja Eclipse IDE

Wszystkie przykłady w tym samouczku zostały napisane przy użyciu Eclipse IDE. Sugerowałbym więc, abyś miał zainstalowaną najnowszą wersję Eclipse na swoim komputerze.

Aby zainstalować Eclipse IDE, pobierz najnowsze pliki binarne Eclipse z https://www.eclipse.org/downloads/. Po pobraniu instalacji rozpakuj dystrybucję binarną w dogodnej lokalizacji. Na przykład wC:\eclipse on windows, lub /usr/local/eclipse on Linux/Unix i na koniec odpowiednio ustaw zmienną PATH.

Eclipse można uruchomić, wykonując następujące polecenia na komputerze z systemem Windows lub po prostu klikając dwukrotnie eclipse.exe

%C:\eclipse\eclipse.exe

Eclipse można uruchomić, wykonując następujące polecenia na komputerze z systemem Unix (Solaris, Linux itp.) -

$/usr/local/eclipse/eclipse

Po udanym uruchomieniu powinien wyświetlić następujący wynik -

Krok 3 - Skonfiguruj biblioteki Lucene Framework

Jeśli uruchomienie się powiedzie, możesz przystąpić do konfiguracji frameworka Lucene. Poniżej przedstawiono proste kroki, aby pobrać i zainstalować framework na swoim komputerze.

https://archive.apache.org/dist/lucene/java/3.6.2/

  • Wybierz, czy chcesz zainstalować Lucene w systemie Windows, czy Unix, a następnie przejdź do następnego kroku, aby pobrać plik .zip dla systemu Windows i plik .tz dla systemu Unix.

  • Pobierz odpowiednią wersję plików binarnych platformy Lucene z witryny https://archive.apache.org/dist/lucene/java/.

  • W czasie pisania tego samouczka pobrałem plik lucene-3.6.2.zip na mój komputer z systemem Windows, a po rozpakowaniu pobranego pliku poda on strukturę katalogów w C: \ lucene-3.6.2 w następujący sposób.

W katalogu znajdziesz wszystkie biblioteki Lucene C:\lucene-3.6.2. Upewnij się, że odpowiednio ustawiłeś zmienną CLASSPATH w tym katalogu, w przeciwnym razie napotkasz problem podczas uruchamiania aplikacji. Jeśli używasz Eclipse, nie jest wymagane ustawianie CLASSPATH, ponieważ wszystkie ustawienia będą wykonywane za pośrednictwem Eclipse.

Gdy skończysz z ostatnim krokiem, możesz przejść do pierwszego przykładu Lucene, który zobaczysz w następnym rozdziale.

W tym rozdziale nauczymy się programowania w Lucene Framework. Zanim zaczniesz pisać swój pierwszy przykład przy użyciu frameworka Lucene, musisz upewnić się, że poprawnie skonfigurowałeś środowisko Lucene, jak wyjaśniono w samouczku Lucene - Konfiguracja środowiska . Zalecane jest posiadanie praktycznej wiedzy o Eclipse IDE.

Przejdźmy teraz do napisania prostej aplikacji wyszukującej, która wydrukuje liczbę znalezionych wyników wyszukiwania. Zobaczymy również listę indeksów utworzonych podczas tego procesu.

Krok 1 - Utwórz projekt Java

Pierwszym krokiem jest stworzenie prostego projektu Java przy użyciu Eclipse IDE. Postępuj zgodnie z opcjąFile > New -> Project i na koniec wybierz Java Projectkreator z listy kreatorów. Teraz nazwij swój projekt jakoLuceneFirstApplication używając okna kreatora w następujący sposób -

Po pomyślnym utworzeniu projektu będziesz mieć następującą zawartość w swoim Project Explorer -

Krok 2 - Dodaj wymagane biblioteki

Dodajmy teraz do naszego projektu bibliotekę rdzeniową Lucene Framework. Aby to zrobić, kliknij prawym przyciskiem myszy nazwę swojego projektuLuceneFirstApplication a następnie skorzystaj z opcji dostępnej w menu kontekstowym: Build Path -> Configure Build Path aby wyświetlić okno ścieżki budowania języka Java w następujący sposób -

Teraz użyj Add External JARs przycisk dostępny pod Libraries aby dodać następujący podstawowy plik JAR z katalogu instalacyjnego Lucene -

  • lucene-core-3.6.2

Krok 3 - Utwórz pliki źródłowe

Utwórzmy teraz rzeczywiste pliki źródłowe w ramach LuceneFirstApplicationprojekt. Najpierw musimy utworzyć pakiet o nazwiecom.tutorialspoint.lucene. Aby to zrobić, kliknij prawym przyciskiem myszy src w sekcji eksploratora pakietów i postępuj zgodnie z opcją: New -> Package.

Następnie stworzymy LuceneTester.java i inne klasy java w ramach com.tutorialspoint.lucene pakiet.

LuceneConstants.java

Ta klasa jest używana do dostarczania różnych stałych do użycia w przykładowej aplikacji.

package com.tutorialspoint.lucene;

public class LuceneConstants {
   public static final String CONTENTS = "contents";
   public static final String FILE_NAME = "filename";
   public static final String FILE_PATH = "filepath";
   public static final int MAX_SEARCH = 10;
}

TextFileFilter.java

Ta klasa jest używana jako .txt file filtr.

package com.tutorialspoint.lucene;

import java.io.File;
import java.io.FileFilter;

public class TextFileFilter implements FileFilter {

   @Override
   public boolean accept(File pathname) {
      return pathname.getName().toLowerCase().endsWith(".txt");
   }
}

Indexer.java

Ta klasa jest używana do indeksowania surowych danych, dzięki czemu możemy je przeszukiwać za pomocą biblioteki Lucene.

package com.tutorialspoint.lucene;

import java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import java.io.IOException;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

public class Indexer {

   private IndexWriter writer;

   public Indexer(String indexDirectoryPath) throws IOException {
      //this directory will contain the indexes
      Directory indexDirectory = 
         FSDirectory.open(new File(indexDirectoryPath));

      //create the indexer
      writer = new IndexWriter(indexDirectory, 
         new StandardAnalyzer(Version.LUCENE_36),true, 
         IndexWriter.MaxFieldLength.UNLIMITED);
   }

   public void close() throws CorruptIndexException, IOException {
      writer.close();
   }

   private Document getDocument(File file) throws IOException {
      Document document = new Document();

      //index file contents
      Field contentField = new Field(LuceneConstants.CONTENTS, new FileReader(file));
      //index file name
      Field fileNameField = new Field(LuceneConstants.FILE_NAME,
         file.getName(),Field.Store.YES,Field.Index.NOT_ANALYZED);
      //index file path
      Field filePathField = new Field(LuceneConstants.FILE_PATH,
         file.getCanonicalPath(),Field.Store.YES,Field.Index.NOT_ANALYZED);

      document.add(contentField);
      document.add(fileNameField);
      document.add(filePathField);

      return document;
   }   

   private void indexFile(File file) throws IOException {
      System.out.println("Indexing "+file.getCanonicalPath());
      Document document = getDocument(file);
      writer.addDocument(document);
   }

   public int createIndex(String dataDirPath, FileFilter filter) 
      throws IOException {
      //get all files in the data directory
      File[] files = new File(dataDirPath).listFiles();

      for (File file : files) {
         if(!file.isDirectory()
            && !file.isHidden()
            && file.exists()
            && file.canRead()
            && filter.accept(file)
         ){
            indexFile(file);
         }
      }
      return writer.numDocs();
   }
}

Searcher.java

Ta klasa służy do przeszukiwania indeksów utworzonych przez indeksatora w celu przeszukania żądanej zawartości.

package com.tutorialspoint.lucene;

import java.io.File;
import java.io.IOException;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.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.FSDirectory;
import org.apache.lucene.util.Version;

public class Searcher {
	
   IndexSearcher indexSearcher;
   QueryParser queryParser;
   Query query;
   
   public Searcher(String indexDirectoryPath) 
      throws IOException {
      Directory indexDirectory = 
         FSDirectory.open(new File(indexDirectoryPath));
      indexSearcher = new IndexSearcher(indexDirectory);
      queryParser = new QueryParser(Version.LUCENE_36,
         LuceneConstants.CONTENTS,
         new StandardAnalyzer(Version.LUCENE_36));
   }
   
   public TopDocs search( String searchQuery) 
      throws IOException, ParseException {
      query = queryParser.parse(searchQuery);
      return indexSearcher.search(query, LuceneConstants.MAX_SEARCH);
   }

   public Document getDocument(ScoreDoc scoreDoc) 
      throws CorruptIndexException, IOException {
      return indexSearcher.doc(scoreDoc.doc);	
   }

   public void close() throws IOException {
      indexSearcher.close();
   }
}

LuceneTester.java

Ta klasa jest używana do testowania możliwości indeksowania i wyszukiwania biblioteki lucene.

package com.tutorialspoint.lucene;

import java.io.IOException;

import org.apache.lucene.document.Document;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;

public class LuceneTester {
	
   String indexDir = "E:\\Lucene\\Index";
   String dataDir = "E:\\Lucene\\Data";
   Indexer indexer;
   Searcher searcher;

   public static void main(String[] args) {
      LuceneTester tester;
      try {
         tester = new LuceneTester();
         tester.createIndex();
         tester.search("Mohan");
      } catch (IOException e) {
         e.printStackTrace();
      } catch (ParseException e) {
         e.printStackTrace();
      }
   }

   private void createIndex() throws IOException {
      indexer = new Indexer(indexDir);
      int numIndexed;
      long startTime = System.currentTimeMillis();	
      numIndexed = indexer.createIndex(dataDir, new TextFileFilter());
      long endTime = System.currentTimeMillis();
      indexer.close();
      System.out.println(numIndexed+" File indexed, time taken: "
         +(endTime-startTime)+" ms");		
   }

   private void search(String searchQuery) throws IOException, ParseException {
      searcher = new Searcher(indexDir);
      long startTime = System.currentTimeMillis();
      TopDocs hits = searcher.search(searchQuery);
      long endTime = System.currentTimeMillis();
   
      System.out.println(hits.totalHits +
         " documents found. Time :" + (endTime - startTime));
      for(ScoreDoc scoreDoc : hits.scoreDocs) {
         Document doc = searcher.getDocument(scoreDoc);
            System.out.println("File: "
            + doc.get(LuceneConstants.FILE_PATH));
      }
      searcher.close();
   }
}

Krok 4 - Tworzenie katalogu Data & Index

Użyliśmy 10 plików tekstowych z plików record1.txt do record10.txt zawierających nazwiska i inne dane uczniów i umieściliśmy je w katalogu E:\Lucene\Data. Dane testowe . Ścieżka katalogu indeksu powinna zostać utworzona jakoE:\Lucene\Index. Po uruchomieniu tego programu możesz zobaczyć listę plików indeksu utworzonych w tym folderze.

Krok 5 - Uruchomienie programu

Po utworzeniu źródła, surowych danych, katalogu danych i katalogu indeksu, jesteś gotowy do kompilacji i uruchomienia programu. Aby to zrobić, zachowaj rozszerzenieLuceneTester.Java aktywna jest karta pliku i użyj rozszerzenia Run opcja dostępna w Eclipse IDE lub użyj Ctrl + F11 skompilować i uruchomić LuceneTesterpodanie. Jeśli aplikacja zostanie pomyślnie uruchomiona, wydrukuje następujący komunikat w konsoli Eclipse IDE -

Indexing E:\Lucene\Data\record1.txt
Indexing E:\Lucene\Data\record10.txt
Indexing E:\Lucene\Data\record2.txt
Indexing E:\Lucene\Data\record3.txt
Indexing E:\Lucene\Data\record4.txt
Indexing E:\Lucene\Data\record5.txt
Indexing E:\Lucene\Data\record6.txt
Indexing E:\Lucene\Data\record7.txt
Indexing E:\Lucene\Data\record8.txt
Indexing E:\Lucene\Data\record9.txt
10 File indexed, time taken: 109 ms
1 documents found. Time :0
File: E:\Lucene\Data\record4.txt

Po pomyślnym uruchomieniu programu będziesz mieć następującą zawartość w swoim index directory -

Proces indeksowania jest jedną z podstawowych funkcji dostarczanych przez Lucene. Poniższy diagram ilustruje proces indeksowania i użycie klas.IndexWriter jest najważniejszym i podstawowym elementem procesu indeksowania.

Dodajemy Document(s) zawierający Field(s) do IndexWriter, który analizuje plik Document(s) używając Analyzer a następnie tworzy / otwiera / edytuje indeksy zgodnie z wymaganiami i przechowuje / aktualizuje je w pliku Directory. IndexWriter służy do aktualizowania lub tworzenia indeksów. Nie jest używany do odczytywania indeksów.

Indeksowanie klas

Poniżej znajduje się lista klas często używanych podczas procesu indeksowania.

S.No. Klasa i opis
1 IndexWriter

Ta klasa działa jako podstawowy składnik, który tworzy / aktualizuje indeksy podczas procesu indeksowania.

2 Informator

Ta klasa reprezentuje lokalizację przechowywania indeksów.

3 Analizator

Ta klasa jest odpowiedzialna za analizę dokumentu i pobranie tokenów / słów z tekstu, który ma być indeksowany. Bez przeprowadzonej analizy IndexWriter nie może utworzyć indeksu.

4 Dokument

Ta klasa reprezentuje wirtualny dokument z polami, gdzie Field jest obiektem, który może zawierać zawartość fizycznego dokumentu, jego metadane i tak dalej. Analizator może zrozumieć tylko dokument.

5 Pole

Jest to najniższa jednostka lub punkt początkowy procesu indeksowania. Reprezentuje relację klucz-wartość, w której klucz jest używany do identyfikowania wartości do indeksowania. Załóżmy, że pole używane do reprezentowania treści dokumentu będzie miało klucz jako „treść”, a wartość może zawierać część lub całość tekstu lub numeryczną zawartość dokumentu. Lucene może indeksować tylko tekst lub zawartość liczbową.

Proces wyszukiwania jest ponownie jedną z podstawowych funkcji dostarczanych przez Lucene. Jego przebieg jest podobny do procesu indeksowania. Podstawowe wyszukiwanie Lucene można przeprowadzić za pomocą następujących klas, które można również określić jako klasy podstawowe dla wszystkich operacji związanych z wyszukiwaniem.

Wyszukiwanie klas

Poniżej znajduje się lista klas często używanych podczas wyszukiwania.

S.No. Klasa i opis
1 IndexSearcher

Ta klasa działa jako podstawowy składnik, który odczytuje / wyszukuje indeksy utworzone po zakończeniu procesu indeksowania. Pobiera instancję katalogu wskazującą na lokalizację zawierającą indeksy.

2 Semestr

Ta klasa jest najniższą jednostką wyszukiwania. Jest podobny do pola w procesie indeksowania.

3 Pytanie

Query jest klasą abstrakcyjną, zawierającą różne metody narzędziowe i nadrzędną dla wszystkich typów zapytań używanych przez Lucene w procesie wyszukiwania.

4 TermQuery

TermQuery jest najczęściej używanym obiektem zapytania i stanowi podstawę wielu złożonych zapytań, z których może korzystać Lucene.

5 TopDocs

TopDocs wskazuje N pierwszych wyników wyszukiwania, które odpowiadają kryteriom wyszukiwania. Jest to prosty pojemnik ze wskaźnikami wskazującymi na dokumenty będące wynikiem wyszukiwania.

Proces indeksowania jest jedną z podstawowych funkcji dostarczanych przez Lucene. Poniższy diagram ilustruje proces indeksowania i użycie klas. IndexWriter jest najważniejszym i podstawowym elementem procesu indeksowania.

Dodajemy Dokument (y) zawierające Pola do IndexWriter, który analizuje Dokument (y) za pomocą Analizatora, a następnie tworzy / otwiera / edytuje indeksy zgodnie z wymaganiami i przechowuje / aktualizuje je w Katalogu . IndexWriter służy do aktualizowania lub tworzenia indeksów. Nie jest używany do odczytywania indeksów.

Teraz pokażemy Ci krok po kroku, jak zacząć rozumieć proces indeksowania na prostym przykładzie.

Utwórz dokument

  • Utwórz metodę, aby uzyskać dokument Lucene z pliku tekstowego.

  • Twórz różne typy pól, które są parami klucz-wartość zawierającymi klucze jako nazwy i wartości jako zawartość do indeksowania.

  • Ustaw pole do analizy lub nie. W naszym przypadku analizowana jest tylko treść, ponieważ może zawierać dane takie jak a, am, are, an itp., Które nie są wymagane w operacjach wyszukiwania.

  • Dodaj nowo utworzone pola do obiektu dokumentu i zwróć je do metody wywołującej.

private Document getDocument(File file) throws IOException {
   Document document = new Document();
   
   //index file contents
   Field contentField = new Field(LuceneConstants.CONTENTS, 
      new FileReader(file));
   
   //index file name
   Field fileNameField = new Field(LuceneConstants.FILE_NAME,
      file.getName(),
      Field.Store.YES,Field.Index.NOT_ANALYZED);
   
   //index file path
   Field filePathField = new Field(LuceneConstants.FILE_PATH,
      file.getCanonicalPath(),
      Field.Store.YES,Field.Index.NOT_ANALYZED);

   document.add(contentField);
   document.add(fileNameField);
   document.add(filePathField);

   return document;
}

Utwórz IndexWriter

Klasa IndexWriter pełni rolę podstawowego składnika, który tworzy / aktualizuje indeksy podczas procesu indeksowania. Wykonaj następujące kroki, aby utworzyć IndexWriter -

Step 1 - Utwórz obiekt IndexWriter.

Step 2 - Utwórz katalog Lucene, który powinien wskazywać lokalizację, w której mają być przechowywane indeksy.

Step 3 - Zainicjuj obiekt IndexWriter utworzony za pomocą katalogu indeksu, standardowego analizatora posiadającego informacje o wersji i inne wymagane / opcjonalne parametry.

private IndexWriter writer;

public Indexer(String indexDirectoryPath) throws IOException {
   //this directory will contain the indexes
   Directory indexDirectory = 
      FSDirectory.open(new File(indexDirectoryPath));
   
   //create the indexer
   writer = new IndexWriter(indexDirectory, 
      new StandardAnalyzer(Version.LUCENE_36),true,
      IndexWriter.MaxFieldLength.UNLIMITED);
}

Rozpocznij proces indeksowania

Poniższy program pokazuje, jak rozpocząć proces indeksowania -

private void indexFile(File file) throws IOException {
   System.out.println("Indexing "+file.getCanonicalPath());
   Document document = getDocument(file);
   writer.addDocument(document);
}

Przykładowa aplikacja

Aby przetestować proces indeksowania, musimy utworzyć test aplikacji Lucene.

Krok Opis
1

Utwórz projekt o nazwie LuceneFirstApplication w pakiecie com.tutorialspoint.lucene, jak wyjaśniono w rozdziale Lucene - Pierwsza aplikacja . Możesz również użyć projektu utworzonego w rozdziale Lucene - Pierwsza aplikacja jako takiego w tym rozdziale, aby zrozumieć proces indeksowania.

2

Utwórz LuceneConstants.java, TextFileFilter.java i Indexer.java, jak wyjaśniono w rozdziale Lucene - pierwsza aplikacja . Resztę plików zachowaj bez zmian.

3

Utwórz LuceneTester.java, jak wspomniano poniżej.

4

Oczyść i skompiluj aplikację, aby upewnić się, że logika biznesowa działa zgodnie z wymaganiami.

LuceneConstants.java

Ta klasa jest używana do dostarczania różnych stałych do użycia w przykładowej aplikacji.

package com.tutorialspoint.lucene;

public class LuceneConstants {
   public static final String CONTENTS = "contents";
   public static final String FILE_NAME = "filename";
   public static final String FILE_PATH = "filepath";
   public static final int MAX_SEARCH = 10;
}

TextFileFilter.java

Ta klasa jest używana jako .txt filtr plików.

package com.tutorialspoint.lucene;

import java.io.File;
import java.io.FileFilter;

public class TextFileFilter implements FileFilter {

   @Override
   public boolean accept(File pathname) {
      return pathname.getName().toLowerCase().endsWith(".txt");
   }
}

Indexer.java

Ta klasa jest używana do indeksowania surowych danych, dzięki czemu możemy je przeszukiwać za pomocą biblioteki Lucene.

package com.tutorialspoint.lucene;

import java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import java.io.IOException;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

public class Indexer {

   private IndexWriter writer;

   public Indexer(String indexDirectoryPath) throws IOException {
      //this directory will contain the indexes
      Directory indexDirectory = 
         FSDirectory.open(new File(indexDirectoryPath));

      //create the indexer
      writer = new IndexWriter(indexDirectory, 
         new StandardAnalyzer(Version.LUCENE_36),true,
         IndexWriter.MaxFieldLength.UNLIMITED);
   }

   public void close() throws CorruptIndexException, IOException {
      writer.close();
   }

   private Document getDocument(File file) throws IOException {
      Document document = new Document();

      //index file contents
      Field contentField = new Field(LuceneConstants.CONTENTS, 
         new FileReader(file));
      
      //index file name
      Field fileNameField = new Field(LuceneConstants.FILE_NAME,
         file.getName(),
         Field.Store.YES,Field.Index.NOT_ANALYZED);
      
      //index file path
      Field filePathField = new Field(LuceneConstants.FILE_PATH,
         file.getCanonicalPath(),
         Field.Store.YES,Field.Index.NOT_ANALYZED);

      document.add(contentField);
      document.add(fileNameField);
      document.add(filePathField);

      return document;
   }   

   private void indexFile(File file) throws IOException {
      System.out.println("Indexing "+file.getCanonicalPath());
      Document document = getDocument(file);
      writer.addDocument(document);
   }

   public int createIndex(String dataDirPath, FileFilter filter) 
      throws IOException {
      //get all files in the data directory
      File[] files = new File(dataDirPath).listFiles();

      for (File file : files) {
         if(!file.isDirectory()
            && !file.isHidden()
            && file.exists()
            && file.canRead()
            && filter.accept(file)
         ){
            indexFile(file);
         }
      }
      return writer.numDocs();
   }
}

LuceneTester.java

Ta klasa jest używana do testowania możliwości indeksowania biblioteki Lucene.

package com.tutorialspoint.lucene;

import java.io.IOException;

public class LuceneTester {
	
   String indexDir = "E:\\Lucene\\Index";
   String dataDir = "E:\\Lucene\\Data";
   Indexer indexer;
   
   public static void main(String[] args) {
      LuceneTester tester;
      try {
         tester = new LuceneTester();
         tester.createIndex();
      } catch (IOException e) {
         e.printStackTrace();
      } 
   }

   private void createIndex() throws IOException {
      indexer = new Indexer(indexDir);
      int numIndexed;
      long startTime = System.currentTimeMillis();	
      numIndexed = indexer.createIndex(dataDir, new TextFileFilter());
      long endTime = System.currentTimeMillis();
      indexer.close();
      System.out.println(numIndexed+" File indexed, time taken: "
         +(endTime-startTime)+" ms");		
   }
}

Tworzenie katalogu danych i indeksów

Użyliśmy 10 plików tekstowych z plików record1.txt do record10.txt zawierających nazwiska i inne dane uczniów i umieściliśmy je w katalogu E:\Lucene\Data. Dane testowe . Ścieżka katalogu indeksu powinna zostać utworzona jakoE:\Lucene\Index. Po uruchomieniu tego programu możesz zobaczyć listę plików indeksu utworzonych w tym folderze.

Uruchomienie programu

Po utworzeniu źródła, surowych danych, katalogu danych i katalogu indeksu, możesz przystąpić do kompilowania i uruchamiania programu. Aby to zrobić, pozostaw aktywną kartę pliku LuceneTester.Java i użyj plikuRun opcja dostępna w Eclipse IDE lub użyj Ctrl + F11 skompilować i uruchomić LuceneTesterpodanie. Jeśli aplikacja zostanie pomyślnie uruchomiona, wydrukuje następujący komunikat w konsoli Eclipse IDE -

Indexing E:\Lucene\Data\record1.txt
Indexing E:\Lucene\Data\record10.txt
Indexing E:\Lucene\Data\record2.txt
Indexing E:\Lucene\Data\record3.txt
Indexing E:\Lucene\Data\record4.txt
Indexing E:\Lucene\Data\record5.txt
Indexing E:\Lucene\Data\record6.txt
Indexing E:\Lucene\Data\record7.txt
Indexing E:\Lucene\Data\record8.txt
Indexing E:\Lucene\Data\record9.txt
10 File indexed, time taken: 109 ms

Po pomyślnym uruchomieniu programu będziesz mieć następującą zawartość w swoim index directory −

W tym rozdziale omówimy cztery główne operacje indeksowania. Operacje te są przydatne w różnych sytuacjach i są używane w całej aplikacji wyszukującej oprogramowanie.

Operacje indeksowania

Poniżej znajduje się lista najczęściej używanych operacji podczas procesu indeksowania.

S.No. Opis operacji
1 Dodaj dokument

Ta operacja jest używana na początkowym etapie procesu indeksowania do tworzenia indeksów dla nowo dostępnej treści.

2 Zaktualizuj dokument

Ta operacja służy do aktualizowania indeksów w celu odzwierciedlenia zmian w zaktualizowanej zawartości. Jest to podobne do odtworzenia indeksu.

3 Usuń dokument

Ta operacja służy do aktualizacji indeksów w celu wykluczenia dokumentów, które nie muszą być indeksowane / przeszukiwane.

4 Opcje pola

Opcje pola określają sposób lub sterują sposobami wyszukiwania zawartości pola.

Proces wyszukiwania jest jedną z podstawowych funkcji oferowanych przez Lucene. Poniższy diagram ilustruje proces i jego zastosowanie. IndexSearcher jest jednym z podstawowych elementów procesu wyszukiwania.

Najpierw tworzymy katalog (y) zawierające indeksy, a następnie przekazujemy go do IndexSearcher, który otwiera katalog za pomocą IndexReader . Następnie tworzymy kwerendę z Term i wykonać wyszukiwanie przy użyciu IndexSearcher przepuszczając zapytanie do wyszukiwarki. IndexSearcher zwraca obiekt TopDocs, który zawiera szczegóły wyszukiwania wraz z identyfikatorami dokumentów Dokumentu, który jest wynikiem operacji wyszukiwania.

Pokażemy teraz stopniowe podejście i pomożemy zrozumieć proces indeksowania na prostym przykładzie.

Utwórz QueryParser

Klasa QueryParser analizuje wprowadzone przez użytkownika dane wejściowe do zapytania Lucene w zrozumiałym formacie. Wykonaj następujące kroki, aby utworzyć QueryParser -

Step 1 - Utwórz obiekt QueryParser.

Step 2 - Zainicjuj obiekt QueryParser utworzony za pomocą standardowego analizatora posiadającego informacje o wersji i nazwę indeksu, na którym ma zostać uruchomione to zapytanie.

QueryParser queryParser;

public Searcher(String indexDirectoryPath) throws IOException {

   queryParser = new QueryParser(Version.LUCENE_36,
      LuceneConstants.CONTENTS,
      new StandardAnalyzer(Version.LUCENE_36));
}

Utwórz IndexSearcher

Klasa IndexSearcher pełni rolę podstawowego komponentu wyszukującego indeksy tworzone podczas procesu indeksowania. Wykonaj następujące kroki, aby utworzyć IndexSearcher -

Step 1 - Utwórz obiekt IndexSearcher.

Step 2 - Utwórz katalog Lucene, który powinien wskazywać lokalizację, w której mają być przechowywane indeksy.

Step 3 - Zainicjuj obiekt IndexSearcher utworzony w katalogu indeksu.

IndexSearcher indexSearcher;

public Searcher(String indexDirectoryPath) throws IOException {
   Directory indexDirectory = 
      FSDirectory.open(new File(indexDirectoryPath));
   indexSearcher = new IndexSearcher(indexDirectory);
}

Wyszukaj

Wykonaj następujące kroki, aby przeprowadzić wyszukiwanie -

Step 1 - Utwórz obiekt Query, analizując wyrażenie wyszukiwania za pomocą QueryParser.

Step 2 - Wykonaj wyszukiwanie, wywołując metodę IndexSearcher.search ().

Query query;

public TopDocs search( String searchQuery) throws IOException, ParseException {
   query = queryParser.parse(searchQuery);
   return indexSearcher.search(query, LuceneConstants.MAX_SEARCH);
}

Pobierz dokument

Poniższy program pokazuje, jak uzyskać dokument.

public Document getDocument(ScoreDoc scoreDoc) 
   throws CorruptIndexException, IOException {
   return indexSearcher.doc(scoreDoc.doc);	
}

Zamknij IndexSearcher

Poniższy program pokazuje, jak zamknąć plik IndexSearcher.

public void close() throws IOException {
   indexSearcher.close();
}

Przykładowa aplikacja

Stwórzmy testową aplikację Lucene do testowania procesu wyszukiwania.

Krok Opis
1

Utwórz projekt o nazwie LuceneFirstApplication w pakiecie com.tutorialspoint.lucene, jak wyjaśniono w rozdziale Lucene - Pierwsza aplikacja . Możesz również użyć projektu utworzonego w rozdziale Lucene - Pierwsza aplikacja jako takiego w tym rozdziale, aby zrozumieć proces wyszukiwania.

2

Utwórz LuceneConstants.java, TextFileFilter.java i Searcher.java, jak wyjaśniono w rozdziale Lucene - pierwsza aplikacja . Resztę plików zachowaj bez zmian.

3

Utwórz LuceneTester.java, jak wspomniano poniżej.

4

Wyczyść i skompiluj aplikację, aby upewnić się, że logika biznesowa działa zgodnie z wymaganiami.

LuceneConstants.java

Ta klasa jest używana do dostarczania różnych stałych do użycia w przykładowej aplikacji.

package com.tutorialspoint.lucene;

public class LuceneConstants {
   public static final String CONTENTS = "contents";
   public static final String FILE_NAME = "filename";
   public static final String FILE_PATH = "filepath";
   public static final int MAX_SEARCH = 10;
}

TextFileFilter.java

Ta klasa jest używana jako .txt filtr plików.

package com.tutorialspoint.lucene;

import java.io.File;
import java.io.FileFilter;

public class TextFileFilter implements FileFilter {

   @Override
   public boolean accept(File pathname) {
      return pathname.getName().toLowerCase().endsWith(".txt");
   }
}

Searcher.java

Ta klasa służy do odczytywania indeksów utworzonych na surowych danych i wyszukiwania danych za pomocą biblioteki Lucene.

package com.tutorialspoint.lucene;

import java.io.File;
import java.io.IOException;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.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.FSDirectory;
import org.apache.lucene.util.Version;

public class Searcher {
	
   IndexSearcher indexSearcher;
   QueryParser queryParser;
   Query query;

   public Searcher(String indexDirectoryPath) throws IOException {
      Directory indexDirectory = 
         FSDirectory.open(new File(indexDirectoryPath));
      indexSearcher = new IndexSearcher(indexDirectory);
      queryParser = new QueryParser(Version.LUCENE_36,
         LuceneConstants.CONTENTS,
         new StandardAnalyzer(Version.LUCENE_36));
   }

   public TopDocs search( String searchQuery) 
      throws IOException, ParseException {
      query = queryParser.parse(searchQuery);
      return indexSearcher.search(query, LuceneConstants.MAX_SEARCH);
   }

   public Document getDocument(ScoreDoc scoreDoc) 
      throws CorruptIndexException, IOException {
      return indexSearcher.doc(scoreDoc.doc);	
   }

   public void close() throws IOException {
      indexSearcher.close();
   }
}

LuceneTester.java

Ta klasa służy do testowania możliwości wyszukiwania biblioteki Lucene.

package com.tutorialspoint.lucene;

import java.io.IOException;

import org.apache.lucene.document.Document;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;

public class LuceneTester {
	
   String indexDir = "E:\\Lucene\\Index";
   String dataDir = "E:\\Lucene\\Data";
   Searcher searcher;

   public static void main(String[] args) {
      LuceneTester tester;
      try {
         tester = new LuceneTester();
         tester.search("Mohan");
      } catch (IOException e) {
         e.printStackTrace();
      } catch (ParseException e) {
         e.printStackTrace();
      }
   }

   private void search(String searchQuery) throws IOException, ParseException {
      searcher = new Searcher(indexDir);
      long startTime = System.currentTimeMillis();
      TopDocs hits = searcher.search(searchQuery);
      long endTime = System.currentTimeMillis();

      System.out.println(hits.totalHits +
         " documents found. Time :" + (endTime - startTime) +" ms");
      for(ScoreDoc scoreDoc : hits.scoreDocs) {
         Document doc = searcher.getDocument(scoreDoc);
         System.out.println("File: "+ doc.get(LuceneConstants.FILE_PATH));
      }
      searcher.close();
   }	
}

Tworzenie katalogu danych i indeksów

Użyliśmy 10 plików tekstowych o nazwach record1.txt do record10.txt zawierających imiona i nazwiska oraz inne szczegóły uczniów i umieściliśmy je w katalogu E: \ Lucene \ Data. Dane testowe . Ścieżkę do katalogu indeksu należy utworzyć jako E: \ Lucene \ Index. Po uruchomieniu programu indeksującego w rozdzialeLucene - Indexing Process, możesz zobaczyć listę plików indeksu utworzonych w tym folderze.

Uruchomienie programu

Po utworzeniu źródła, surowych danych, katalogu danych, katalogu indeksów i indeksów, możesz kontynuować kompilację i uruchomienie programu. Aby to zrobić, zachowajLuceneTester.Java plik jest aktywna i użyj opcji Uruchom dostępnej w środowisku Eclipse IDE lub użyj Ctrl + F11 skompilować i uruchomić LuceneTesterapplication. Jeśli aplikacja zostanie pomyślnie uruchomiona, wydrukuje następujący komunikat w konsoli Eclipse IDE -

1 documents found. Time :29 ms
File: E:\Lucene\Data\record4.txt

Widzieliśmy w poprzednim rozdziale Lucene - Search OperationLucene używa IndexSearcher do wyszukiwania i używa obiektu Query utworzonego przez QueryParser jako dane wejściowe. W tym rozdziale omówimy różne typy obiektów Query i różne sposoby ich programowego tworzenia. Tworzenie różnych typów obiektów Query daje kontrolę nad rodzajem wyszukiwania.

Rozważmy przypadek wyszukiwania zaawansowanego, oferowanego przez wiele aplikacji, w których użytkownicy mają wiele opcji ograniczania wyników wyszukiwania. Dzięki programowaniu zapytań możemy bardzo łatwo osiągnąć to samo.

Poniżej znajduje się lista typów zapytań, które omówimy w odpowiednim czasie.

S.No. Klasa i opis
1 TermQuery

Ta klasa działa jako podstawowy składnik, który tworzy / aktualizuje indeksy podczas procesu indeksowania.

2 TermRangeQuery

TermRangeQuery jest używane, gdy ma być przeszukiwany zakres terminów tekstowych.

3 PrefixQuery

PrefixQuery służy do dopasowywania dokumentów, których indeks zaczyna się od określonego ciągu.

4 BooleanQuery

BooleanQuery służy do wyszukiwania dokumentów, które są wynikiem wielu zapytań przy użyciu AND, OR lub NOT operatorzy.

5 PhraseQuery

Zapytanie frazowe służy do wyszukiwania dokumentów zawierających określoną sekwencję terminów.

6 WildCardQuery

WildcardQuery służy do wyszukiwania dokumentów przy użyciu symboli wieloznacznych, takich jak „*” dla dowolnej sekwencji znaków ,? dopasowanie pojedynczego znaku.

7 FuzzyQuery

FuzzyQuery służy do wyszukiwania dokumentów przy użyciu implementacji rozmytej, która jest przybliżonym wyszukiwaniem w oparciu o algorytm edycji odległości.

8 MatchAllDocsQuery

MatchAllDocsQuery, jak sugeruje nazwa, pasuje do wszystkich dokumentów.

W jednym z naszych poprzednich rozdziałów widzieliśmy, że Lucene używa IndexWriter do analizy dokumentów za pomocą analizatora, a następnie tworzy / otwiera / edytuje indeksy zgodnie z wymaganiami. W tym rozdziale omówimy różne typy obiektów Analizatora i inne istotne obiekty, które są używane podczas procesu analizy. Zrozumienie procesu analizy i sposobu działania analizatorów zapewni doskonały wgląd w to, jak Lucene indeksuje dokumenty.

Poniżej znajduje się lista obiektów, które omówimy w odpowiednim czasie.

S.No. Klasa i opis
1 Znak

Token reprezentuje tekst lub słowo w dokumencie z odpowiednimi szczegółami, takimi jak metadane (pozycja, przesunięcie początkowe, przesunięcie końcowe, typ tokena i przyrost pozycji).

2 TokenStream

TokenStream jest wynikiem procesu analizy i składa się z serii tokenów. To klasa abstrakcyjna.

3 Analizator

Jest to abstrakcyjna klasa bazowa dla każdego typu analizatora.

4 WhitespaceAnalyzer

Ten analizator dzieli tekst w dokumencie na podstawie białych znaków.

5 SimpleAnalyzer

Ten analizator dzieli tekst w dokumencie na podstawie znaków innych niż litery i umieszcza tekst małymi literami.

6 StopAnalyzer

Ten analizator działa tak samo jak SimpleAnalyzer i usuwa popularne słowa, takie jak 'a', 'an', 'the', itp.

7 StandardAnalyzer

Jest to najbardziej wyrafinowany analizator i jest w stanie obsłużyć nazwiska, adresy e-mail itp. Zmniejsza wielkość każdego tokena i usuwa popularne słowa i znaki interpunkcyjne, jeśli takie istnieją.

W tym rozdziale przyjrzymy się porządkowi sortowania, w którym Lucene domyślnie podaje wyniki wyszukiwania lub można nim manipulować w razie potrzeby.

Sortowanie według trafności

Jest to domyślny tryb sortowania używany przez Lucene. Lucene podaje wyniki według najbardziej odpowiedniego hitu na górze.

private void sortUsingRelevance(String searchQuery)
   throws IOException, ParseException {
   searcher = new Searcher(indexDir);
   long startTime = System.currentTimeMillis();
   
   //create a term to search file name
   Term term = new Term(LuceneConstants.FILE_NAME, searchQuery);
   //create the term query object
   Query query = new FuzzyQuery(term);
   searcher.setDefaultFieldSortScoring(true, false);
   //do the search
   TopDocs hits = searcher.search(query,Sort.RELEVANCE);
   long endTime = System.currentTimeMillis();

   System.out.println(hits.totalHits +
      " documents found. Time :" + (endTime - startTime) + "ms");
   for(ScoreDoc scoreDoc : hits.scoreDocs) {
      Document doc = searcher.getDocument(scoreDoc);
      System.out.print("Score: "+ scoreDoc.score + " ");
      System.out.println("File: "+ doc.get(LuceneConstants.FILE_PATH));
   }
   searcher.close();
}

Sortowanie według IndexOrder

Ten tryb sortowania jest używany przez Lucene. Tutaj pierwszy zindeksowany dokument jest wyświetlany jako pierwszy w wynikach wyszukiwania.

private void sortUsingIndex(String searchQuery)
   throws IOException, ParseException {
   searcher = new Searcher(indexDir);
   long startTime = System.currentTimeMillis();
   
   //create a term to search file name
   Term term = new Term(LuceneConstants.FILE_NAME, searchQuery);
   //create the term query object
   Query query = new FuzzyQuery(term);
   searcher.setDefaultFieldSortScoring(true, false);
   //do the search
   TopDocs hits = searcher.search(query,Sort.INDEXORDER);
   long endTime = System.currentTimeMillis();

   System.out.println(hits.totalHits +
      " documents found. Time :" + (endTime - startTime) + "ms");
   for(ScoreDoc scoreDoc : hits.scoreDocs) {
      Document doc = searcher.getDocument(scoreDoc);
      System.out.print("Score: "+ scoreDoc.score + " ");
      System.out.println("File: "+ doc.get(LuceneConstants.FILE_PATH));
   }
   searcher.close();
}

Przykładowa aplikacja

Stwórzmy testową aplikację Lucene, aby przetestować proces sortowania.

Krok Opis
1

Utwórz projekt o nazwie LuceneFirstApplication w pakiecie com.tutorialspoint.lucene, jak wyjaśniono w rozdziale Lucene - Pierwsza aplikacja . Możesz również użyć projektu utworzonego w rozdziale Lucene - Pierwsza aplikacja jako takiego w tym rozdziale, aby zrozumieć proces wyszukiwania.

2

Utwórz LuceneConstants.java i Searcher.java, jak wyjaśniono w rozdziale Lucene - pierwsza aplikacja . Resztę plików zachowaj bez zmian.

3

Utwórz LuceneTester.java, jak wspomniano poniżej.

4

Wyczyść i skompiluj aplikację, aby upewnić się, że logika biznesowa działa zgodnie z wymaganiami.

LuceneConstants.java

Ta klasa jest używana do dostarczania różnych stałych do użycia w przykładowej aplikacji.

package com.tutorialspoint.lucene;

public class LuceneConstants {
   public static final String CONTENTS = "contents";
   public static final String FILE_NAME = "filename";
   public static final String FILE_PATH = "filepath";
   public static final int MAX_SEARCH = 10;
}

Searcher.java

Ta klasa służy do odczytywania indeksów utworzonych na surowych danych i wyszukiwania danych za pomocą biblioteki Lucene.

package com.tutorialspoint.lucene;

import java.io.File;
import java.io.IOException;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

public class Searcher {
	
IndexSearcher indexSearcher;
   QueryParser queryParser;
   Query query;

   public Searcher(String indexDirectoryPath) throws IOException {
      Directory indexDirectory 
         = FSDirectory.open(new File(indexDirectoryPath));
      indexSearcher = new IndexSearcher(indexDirectory);
      queryParser = new QueryParser(Version.LUCENE_36,
         LuceneConstants.CONTENTS,
         new StandardAnalyzer(Version.LUCENE_36));
   }

   public TopDocs search( String searchQuery) 
      throws IOException, ParseException {
      query = queryParser.parse(searchQuery);
      return indexSearcher.search(query, LuceneConstants.MAX_SEARCH);
   }

   public TopDocs search(Query query) 
      throws IOException, ParseException {
      return indexSearcher.search(query, LuceneConstants.MAX_SEARCH);
   }

   public TopDocs search(Query query,Sort sort) 
      throws IOException, ParseException {
      return indexSearcher.search(query, 
         LuceneConstants.MAX_SEARCH,sort);
   }

   public void setDefaultFieldSortScoring(boolean doTrackScores, 
      boolean doMaxScores) {
      indexSearcher.setDefaultFieldSortScoring(
         doTrackScores,doMaxScores);
   }

   public Document getDocument(ScoreDoc scoreDoc) 
      throws CorruptIndexException, IOException {
      return indexSearcher.doc(scoreDoc.doc);	
   }

   public void close() throws IOException {
      indexSearcher.close();
   }
}

LuceneTester.java

Ta klasa służy do testowania możliwości wyszukiwania biblioteki Lucene.

package com.tutorialspoint.lucene;

import java.io.IOException;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.TopDocs;

public class LuceneTester {
	
   String indexDir = "E:\\Lucene\\Index";
   String dataDir = "E:\\Lucene\\Data";
   Indexer indexer;
   Searcher searcher;

   public static void main(String[] args) {
      LuceneTester tester;
      try {
          tester = new LuceneTester();
          tester.sortUsingRelevance("cord3.txt");
          tester.sortUsingIndex("cord3.txt");
      } catch (IOException e) {
          e.printStackTrace();
      } catch (ParseException e) {
          e.printStackTrace();
      }		
   }

   private void sortUsingRelevance(String searchQuery)
      throws IOException, ParseException {
      searcher = new Searcher(indexDir);
      long startTime = System.currentTimeMillis();
      
      //create a term to search file name
      Term term = new Term(LuceneConstants.FILE_NAME, searchQuery);
      //create the term query object
      Query query = new FuzzyQuery(term);
      searcher.setDefaultFieldSortScoring(true, false);
      //do the search
      TopDocs hits = searcher.search(query,Sort.RELEVANCE);
      long endTime = System.currentTimeMillis();

      System.out.println(hits.totalHits +
         " documents found. Time :" + (endTime - startTime) + "ms");
      for(ScoreDoc scoreDoc : hits.scoreDocs) {
         Document doc = searcher.getDocument(scoreDoc);
         System.out.print("Score: "+ scoreDoc.score + " ");
         System.out.println("File: "+ doc.get(LuceneConstants.FILE_PATH));
      }
      searcher.close();
   }

   private void sortUsingIndex(String searchQuery)
      throws IOException, ParseException {
      searcher = new Searcher(indexDir);
      long startTime = System.currentTimeMillis();
      //create a term to search file name
      Term term = new Term(LuceneConstants.FILE_NAME, searchQuery);
      //create the term query object
      Query query = new FuzzyQuery(term);
      searcher.setDefaultFieldSortScoring(true, false);
      //do the search
      TopDocs hits = searcher.search(query,Sort.INDEXORDER);
      long endTime = System.currentTimeMillis();

      System.out.println(hits.totalHits +
      " documents found. Time :" + (endTime - startTime) + "ms");
      for(ScoreDoc scoreDoc : hits.scoreDocs) {
         Document doc = searcher.getDocument(scoreDoc);
         System.out.print("Score: "+ scoreDoc.score + " ");
         System.out.println("File: "+ doc.get(LuceneConstants.FILE_PATH));
      }
      searcher.close();
   }
}

Tworzenie katalogu danych i indeksów

Użyliśmy 10 plików tekstowych z plików record1.txt do record10.txt zawierających nazwiska i inne dane uczniów i umieściliśmy je w katalogu E:\Lucene\Data. Dane testowe . Ścieżkę do katalogu indeksu należy utworzyć jako E: \ Lucene \ Index. Po uruchomieniu programu indeksującego w rozdzialeLucene - Indexing Process, możesz zobaczyć listę plików indeksu utworzonych w tym folderze.

Uruchomienie programu

Po utworzeniu źródła, surowych danych, katalogu danych, katalogu indeksów i indeksów, możesz skompilować i uruchomić swój program. Aby to zrobić, zachowajLuceneTester.Java plik jest aktywna i użyj opcji Uruchom dostępnej w środowisku Eclipse IDE lub użyj Ctrl + F11 skompilować i uruchomić LuceneTesterpodanie. Jeśli aplikacja zostanie pomyślnie uruchomiona, wydrukuje następujący komunikat w konsoli Eclipse IDE -

10 documents found. Time :31ms
Score: 1.3179655 File: E:\Lucene\Data\record3.txt
Score: 0.790779 File: E:\Lucene\Data\record1.txt
Score: 0.790779 File: E:\Lucene\Data\record2.txt
Score: 0.790779 File: E:\Lucene\Data\record4.txt
Score: 0.790779 File: E:\Lucene\Data\record5.txt
Score: 0.790779 File: E:\Lucene\Data\record6.txt
Score: 0.790779 File: E:\Lucene\Data\record7.txt
Score: 0.790779 File: E:\Lucene\Data\record8.txt
Score: 0.790779 File: E:\Lucene\Data\record9.txt
Score: 0.2635932 File: E:\Lucene\Data\record10.txt
10 documents found. Time :0ms
Score: 0.790779 File: E:\Lucene\Data\record1.txt
Score: 0.2635932 File: E:\Lucene\Data\record10.txt
Score: 0.790779 File: E:\Lucene\Data\record2.txt
Score: 1.3179655 File: E:\Lucene\Data\record3.txt
Score: 0.790779 File: E:\Lucene\Data\record4.txt
Score: 0.790779 File: E:\Lucene\Data\record5.txt
Score: 0.790779 File: E:\Lucene\Data\record6.txt
Score: 0.790779 File: E:\Lucene\Data\record7.txt
Score: 0.790779 File: E:\Lucene\Data\record8.txt
Score: 0.790779 File: E:\Lucene\Data\record9.txt