Wprowadzenie do Lucene

Wprowadzenie do Lucene
W tej lekcji zrozumiemy działanie za jedną z najpotężniejszych wyszukiwarki pełnotekstowego, Apache Lucene. Dzięki Apache Lucene możemy użyć interfejsów API, które ujawnia w wielu językach programowania i buduje potrzebne funkcje. Lucene jest jednym z najpotężniejszych silników, na którym buduje się Elasticsearch. Zanim zaczniemy od aplikacji, która pokazuje działanie Apache Lucene, zrozumiemy, jak działa Lucene i wiele jej komponentów. Zacznijmy.

Dlaczego lucene jest potrzebne?

Wyszukiwanie jest jedną z najczęstszych operacji, które wykonujemy wiele razy dziennie. To wyszukiwanie może odbywać się na wielu stronach internetowych, które istnieją w Internecie lub aplikacji muzycznej lub repozytorium kodu lub kombinacja wszystkich z nich. Można pomyśleć, że prosta relacyjna baza danych może również obsługiwać wyszukiwanie. To jest poprawne. Bazy danych, takie jak MySQL obsługuje wyszukiwanie w pełnym teście. Ale co z siecią lub aplikacją muzyczną lub repozytorium kodu lub kombinacją wszystkich z nich? Baza danych nie może przechowywać tych danych w swoich kolumnach. Nawet jeśli tak, uruchomienie tego dużego wyszukiwania zajmie nie do przyjęcia.

Wyszukiwarka w pełnym teście jest w stanie uruchomić zapytanie na miliony plików jednocześnie. Prędkość, w której dane są przechowywane w dzisiejszej aplikacji, jest ogromna. Uruchomienie pełnego tekstu wyszukiwania tego rodzaju ilości danych jest trudnym zadaniem. Wynika to z faktu, że potrzebne informacje mogą istnieć w jednym pliku z miliardów plików przechowywanych w Internecie.

Jak działa Lucene?

Oczywiste pytanie, które powinno przyjechać na twój umysł, brzmi: w jaki sposób Lucene jest tak szybko w uruchomieniu zapytań o pełny tekst? Odpowiedź na to oczywiście jest przy pomocy wskaźników, które tworzy. Ale zamiast tworzyć klasyczny indeks, Lucene korzysta Odwrócone wskaźniki.

W klasycznym indeksie dla każdego dokumentu zbieramy pełną listę słów lub warunków zawiera dokument. W indeksie odwróconym, dla każdego słowa we wszystkich dokumentach, przechowujemy to, co dokument i pozycja tego słowa/termin można znaleźć. Jest to algorytm wysokiego standardu, który sprawia, że ​​wyszukiwanie jest bardzo łatwe. Rozważ następujący przykład tworzenia klasycznego indeksu:

DOC1 -> „this”, „is”, „proste”, „Lucene”, „próbka”, „klasyczna”, „odwrócone”, „indeks”
Doc2 -> „Running”, „ElasticSearch”, „Ubuntu”, „aktualizacja”
Doc3 -> „Rabbitmq”, „Lucene”, „Kafka”, „”, „Spring”, „boot”

Jeśli użyjemy indeksu odwróconego, będziemy mieli wskaźniki takie jak:

Ten -> (2, 71)
Lucene -> (1, 9), (12,87)
Apache -> (12, 91)
Framework -> (32, 11)

Odwrócone indeksy są znacznie łatwiejsze w utrzymaniu. Załóżmy, że jeśli chcemy znaleźć Apache w moich warunkach, będę miał od razu odpowiedzi z odwróconymi indeksami, podczas gdy w przypadku klasycznego wyszukiwania będzie działać na pełnych dokumentach, które mogły nie być możliwe w scenariuszach w czasie rzeczywistym.

LUCENE Workflow

Zanim Lucene będzie faktycznie przeszukać dane, musi wykonywać kroki. Wizualizujmy te kroki w celu lepszego zrozumienia:

LUCENE Workflow

Jak pokazano na schemacie, tak się dzieje w Lucene:

  1. Lucene jest podawana dokumentami i innymi źródłami danych
  2. Dla każdego dokumentu Lucene najpierw przekształca te dane na zwykły tekst, a następnie analizy przekształca to źródło na zwykły tekst
  3. Dla każdego terminu w prostym tekście tworzone są odwrócone wskaźniki
  4. Wskaźniki są gotowe do przeszukania

Dzięki temu przepływowi pracy Lucene jest bardzo mocną wyszukiwarką pełnotekstową. Ale to jedyna część Lucene spełnia. Musimy wykonać pracę samodzielnie. Spójrzmy na potrzebne elementy indeksowania.

Komponenty Lucene

W tej sekcji opisamy podstawowe komponenty i podstawowe klasy Lucene używane do tworzenia wskaźników:

  • Katalogi: Indeks Lucene przechowuje dane w normalnym systemie systemów plików lub w pamięci, jeśli potrzebujesz większej wydajności. To całkowicie wybór aplikacji do przechowywania danych wszędzie tam, gdzie chce, baza danych, pamięć RAM lub dysk.
  • Dokumenty: Dane, które zasilamy do silnika Lucene, należy przekonwertować na zwykły tekst. Aby to zrobić, tworzymy obiekt dokumentu, który reprezentuje to źródło danych. Później, kiedy uruchomimy zapytanie, w rezultacie otrzymamy listę obiektów dokumentów, które spełniają przekazane zapytanie.
  • Pola: Dokumenty są wypełnione zbiorem pól. Pole to po prostu para (Nazwa, wartość) rzeczy. Tak więc, tworząc nowy obiekt dokumentu, musimy go wypełnić tego rodzaju sparowanymi danymi. Gdy pole jest odwrócone, wartość pola jest tokenizowana i jest dostępna do wyszukiwania. Teraz, podczas gdy używamy pól, nie jest ważne przechowywanie faktycznej pary, ale tylko odwrócone indeksowane. W ten sposób możemy zdecydować, jakie dane można przeszukiwać i nie ważne do zapisania. Spójrzmy na przykład tutaj:

    Indeksowanie pola

    W powyższej tabeli postanowiliśmy przechowywać niektóre pola, a inne nie są przechowywane. Pole nadwozia nie jest przechowywane, ale indeksowane. Oznacza to, że wiadomość e -mail zostanie zwrócona w wyniku uruchomienia zapytania jednego z warunków zawartości ciała.

  • Warunki: Warunki reprezentują słowo z tekstu. Warunki są wyodrębnione z analizy i tokenizacji wartości pól, zatem Termin jest najmniejszym urządzeniem, na którym prowadzono wyszukiwanie.
  • Analizy: Analizator jest najważniejszą częścią procesu indeksowania i wyszukiwania. Jest to analizator, który przekazuje zwykły tekst w tokeny i warunki, aby można je było przeszukać. Cóż, to nie jedyna odpowiedzialność analizatora. Analizator używa tokenizatora do robienia tokenów. Analizator wykonuje również następujące zadania:
    • STEMMING: analizator przekształca słowo w łodygę. Oznacza to, że „kwiaty” są przekształcane w słowo łodygi „kwiat”. Tak więc, gdy uruchomi się wyszukiwanie „kwiatu”, dokument zostanie zwrócony.
    • Filtrowanie: analizator filtruje również słowa, takie jak „The”, to „itp. ponieważ te słowa nie przyciągają żadnych pytań do uruchomienia i nie są produktywne.
    • Normalizacja: Proces ten usuwa akcenty i inne oznaczenia znaków.

    To tylko normalna odpowiedzialność StandardAnalyzer.

Przykładowa aplikacja

Będziemy używać jednego z wielu archetypów Maven, aby utworzyć przykładowy projekt dla naszego przykładu. Aby utworzyć projekt, wykonaj następujące polecenie w katalogu, którego użyjesz jako obszar roboczy:

MVN ArcheType: Generate -dgroupid = com.Linuxhint.Przykład -DartifactID = LH -Luceneexample -darchetypeartifactID = Maven -ArcheType -QuickStart -dinteractiveMode = false

Jeśli po raz pierwszy uruchomisz Maven, wykonanie polecenia generowania potrwa kilka sekund, ponieważ Maven musi pobrać wszystkie wymagane wtyczki i artefakty, aby zadanie generowania. Oto jak wygląda wyjście projektu:

Konfiguracja projektu

Po utworzeniu projektu możesz otworzyć go w ulubionym IDE. Kolejnym krokiem jest dodanie odpowiednich zależności Maven do projektu. Oto pom.plik XML z odpowiednimi zależnościami:



org.Apache.Lucene
Lucene-Core
4.6.0


org.Apache.Lucene
Lucene-analizers-common
4.6.0

Wreszcie, aby zrozumieć wszystkie słoiki, które są dodawane do projektu, gdy dodamy tę zależność, możemy uruchomić proste polecenie Maven, które pozwala nam zobaczyć pełne drzewo zależności projektu, gdy dodamy do niego zależności. Oto polecenie, którego możemy użyć:

Zależność MVN: drzewo

Po uruchomieniu tego polecenia pokaże nam następujące drzewo zależności:

Na koniec tworzymy klasę SimpleIndexer, która działa

pakiet com.Linuxhint.przykład;
Importuj Java.io.Plik;
Importuj Java.io.FileReader;
Importuj Java.io.IoException;
import org.Apache.Lucene.analiza.Analizator;
import org.Apache.Lucene.analiza.standard.StandardAnalyzer;
import org.Apache.Lucene.dokument.Dokument;
import org.Apache.Lucene.dokument.STEARDFIELD;
import org.Apache.Lucene.dokument.Pole tekstowe;
import org.Apache.Lucene.indeks.IndideWriter;
import org.Apache.Lucene.indeks.IndexWriterConfig;
import org.Apache.Lucene.sklep.FSDirectory;
import org.Apache.Lucene.Util.Wersja;
Klasa publiczna SimpleIndexer
Private static Final String indexDirectory = "/Users/Shubham/Somethere/Lh-LuceeEXample/index";
Private Static Final String dirtobeIndexed = "/Users/Shubham/Somethere/Lh-LuceeEXample/src/main/java/com/linuxhint/example";
public static void main (string [] args) rzuca wyjątek
Plik indexDir = nowy plik (indeksDirectory);
Plik datadir = nowy plik (dirtobeIndexed);
SimpleIndexer indexer = new SimpleIndexer ();
int numdexed = indekser.index (indexDir, dataDir);
System.na zewnątrz.println („Całkowite pliki indeksowane” + numdexed);

indeks private int indeks (indeksowanie plików, plik dataDir) rzuca ioException
Analyzer Analyzer = nowy StandardAnalyzer (wersja.Lucene_46);
IndexWriterConfig config = new indexWriterConfig (wersja.Lucene_46,
analizator);
IndexWriter indexWriter = nowy indeksWiter (FSDirectory.Otwarte (indexDir),
config);
Plik [] pliki = datadir.ListFiles ();
dla (plik f: pliki)
System.na zewnątrz.println („plik indeksujący” + f.getCanonicalPath ());
Document doc = new Document ();
Doc.add (nowy tekstfield („content”, nowy FileReader (f)));
Doc.Dodaj (nowy STORODEFFIEL („Filename”, F.getCanonicalPath ()));
indideWriter.addDocument (DOC);

int numIndexed = indideWriter.maxdoc ();
indideWriter.zamknąć();
return numindexed;

W tym kodzie właśnie stworzyliśmy instancję dokumentu i dodaliśmy nowe pole reprezentujące zawartość pliku. Oto dane wyjściowe, które otrzymujemy podczas uruchamiania tego pliku:

Indeksowanie pliku/użytkowników/shubham/gdzieś/lh-luceneexample/src/main/java/com/linuxhint/example/simpleindexer.Jawa
Całkowite pliki indeksowane 1

Ponadto w projekcie powstaje nowy katalog z następującą treścią:

Dane indeksu

Przeanalizujemy, co wszystkie pliki są tworzone w tym indeksie na więcej lekcjach, które pojawią się Lucene.

Wniosek

W tej lekcji przyjrzeliśmy się, jak działa Apache Lucene, a także złożyliśmy prostą przykładową aplikację opartą na Maven i Javie.