Tražilica Lucene: Moćna, fleksibilna i besplatna

Neka vas mali broj verzije - 0,04 od kolovoza 2000. - ne zavara. Tražilica Lucene robustan je, moćan i fleksibilan alat za pretraživanje, spreman za rješavanje mnogih uobičajenih problema pretraživanja. A budući da je sada dostupan pod fleksibilnijom LGPL licencom otvorenog koda, i cijena je (besplatna!) U pravu.

Doug Cutting, iskusni programer alata za pretraživanje i pronalaženje teksta, stvorio je Lucene. Cutting je glavni autor V-Twin tražilice (dio napora Appleovog operativnog sustava Copland) i trenutno je stariji arhitekt u Exciteu. Dizajnirao je Lucene kako bi olakšao dodavanje mogućnosti indeksiranja i pretraživanja širokom spektru aplikacija, uključujući:

  • E-pošta s kojom se može pretraživati: aplikacija za e-poštu korisnicima može omogućiti pretraživanje arhiviranih poruka i dodavanje novih poruka u indeks čim stignu.
  • Internetsko pretraživanje dokumentacije: Čitač dokumentacije - na CD-u, na mreži ili ugrađen u aplikaciju - mogao bi omogućiti korisnicima da pretražuju internetsku dokumentaciju ili arhivirane publikacije.
  • Web stranice koje se mogu pretraživati: Web preglednik ili proxy poslužitelj mogu izgraditi osobnu tražilicu za indeksiranje svake web stranice koju je korisnik posjetio, omogućavajući korisnicima lako ponovno posjećivanje stranica.
  • Pretraživanje web stranice: CGI program mogao bi omogućiti korisnicima da pretražuju vašu web stranicu.
  • Pretraživanje sadržaja: aplikacija može dopustiti korisniku da pretražuje spremljene dokumente za određeni sadržaj; ovo bi se moglo integrirati u dijalog Otvoreni dokument.
  • Kontrola verzija i upravljanje sadržajem: Sustav za upravljanje dokumentima može indeksirati dokumente ili verzije dokumenata, tako da se lako mogu dohvatiti.
  • Vijesti i feedovi uslužnih usluga: Poslužitelj vijesti ili relej može indeksirati članke čim stignu.

Naravno, mnoge tražilice mogle bi izvoditi većinu tih funkcija, ali malo alata za pretraživanje s otvorenim kodom nudi Luceneovu jednostavnost upotrebe, brzu implementaciju i fleksibilnost.

Lucene sam prvi put koristio kada sam razvijao Eyebrowse, alat otvorenog koda temeljen na Javi za katalogizaciju i pregledavanje mailing lista. (Pogledajte Resurse za vezu.) Osnovni zahtjev za Eyebrowse bila je fleksibilna mogućnost pretraživanja i pretraživanja poruka. Zahtijevalo je komponentu indeksiranja i pretraživanja koja će učinkovito ažurirati bazu indeksa kako stižu nove poruke, omogućiti višestrukim korisnicima da istovremeno pretražuju i ažuriraju bazu indeksa i skalirati u arhive koje sadrže milijune poruka.

Svaka druga tražilica s otvorenim kodom koju sam procijenio, uključujući Swish-E, Glimpse, iSearch i libibex, na neki je način bila slabo prilagođena zahtjevima Eyebrowsea. To bi integraciju učinilo problematičnom i / ili dugotrajnom. S Lucene sam za nešto više od pola dana, od početnog preuzimanja do potpuno radnog koda, dodao Eyebrowse indeksiranje i pretraživanje! To je bilo manje od jedne desetine razvojnog vremena koje sam planirao i polučilo je čvrsto integrirani i bogatiji rezultat od bilo kojeg drugog alata za pretraživanje koji sam smatrao.

Kako tražilice rade

Stvaranje i održavanje obrnutog indeksa središnji je problem prilikom izgradnje učinkovite tražilice ključnih riječi. Da biste indeksirali dokument, prvo ga morate skenirati kako biste stvorili popis knjiženja. Knjiženja opisuju pojave riječi u dokumentu; oni obično uključuju riječ, ID dokumenta i moguće mjesto ili mjesta ili učestalost riječi u dokumentu.

Ako knjiženja smatrate skupima obrasca , skup dokumenata dobit će popis knjiženja sortiranih prema ID-u dokumenta. Ali da biste učinkovito pronašli dokumente koji sadrže određene riječi, umjesto toga trebali biste razvrstati knjiženja po riječi (ili i po riječi i po dokumentu, što će ubrzati pretraživanje više riječi). U tom smislu, izrada indeksa pretraživanja u osnovi predstavlja problem sortiranja. Indeks pretraživanja je popis knjiženja poredanih po riječi.

Inovativna provedba

Većina tražilica koristi B-stabla za održavanje indeksa; relativno su stabilni s obzirom na umetanje i imaju dobro ponašane I / O karakteristike (traženje i umetanje su O (log n) operacije). Lucene ima malo drugačiji pristup: umjesto da održava jedan indeks, on gradi više segmenata indeksa i povremeno ih spaja. Za svaki indeksirani novi dokument Lucene stvara novi indeksni segment, ali brzo spaja male segmente s većima - to zadržava ukupan broj segmenata malim, tako da pretraživanja ostaju brza. Da bi optimizirao indeks za brzo pretraživanje, Lucene može spojiti sve segmente u jedan, što je korisno za rijetko ažurirane indekse. Kako bi spriječio sukobe (ili blokiranje troškova) između čitača indeksa i pisaca, Lucene nikada ne mijenja segmente na mjestu, već samo stvara nove. Pri spajanju segmenata,Lucene napiše novi segment i izbriše stari - nakon što ga zatvore bilo koji aktivni čitatelji. Ovaj pristup dobro se skalira, nudi programeru visok stupanj fleksibilnosti u trgovanju brzinom indeksiranja za brzinu pretraživanja i ima poželjne I / O karakteristike i za spajanje i za pretraživanje.

Segment indeksa Lucene sastoji se od nekoliko datoteka:

  • Kazalo rječnika koji sadrži jedan unos za svakih 100 unosa u rječniku
  • Rječnik koji sadrži jedan unos za svaku jedinstvenu riječ
  • Datoteka knjiženja koja sadrži unos za svako knjiženje

Budući da Lucene nikada ne ažurira segmente na mjestu, oni se mogu pohraniti u ravne datoteke umjesto u komplicirana B-stabla. Za brzo dohvaćanje, indeks rječnika sadrži pomake u datoteku rječnika, a rječnik sadrži pomake u datoteku knjiženja. Lucene također implementira razne trikove za komprimiranje rječnika i objavljivanje datoteka - smanjujući tako I / O disk - bez nanošenja značajnih troškova procesora.

Procjena pretraživača

Ostale široko korištene tražilice s otvorenim kodom uključuju Swish-E, Glimpse, libibex, freeWAIS i iSearch. Kao i svaki softverski paket, svaki je optimiziran za upotrebu u određenim situacijama; ove je alate često teško rasporediti izvan predviđenih domena. Pri procjeni tražilice uzmite u obzir sljedeće značajke:

  • Inkrementalno u odnosu na batch indeksiranje: neke tražilice podržavaju samo batch indeksiranje; nakon što stvore indeks za skup dokumenata, dodavanje novih dokumenata postaje teško bez ponovnog indeksiranja svih dokumenata. Inkrementalno indeksiranje omogućuje jednostavno dodavanje dokumenata u postojeći indeks. Za neke aplikacije, poput onih koje obrađuju feedove podataka uživo, inkrementalno indeksiranje je presudno. Lucene podržava obje vrste indeksiranja.
  • Izvori podataka: Mnoge tražilice mogu indeksirati samo datoteke ili web stranice. To onemogućava aplikacije u kojima indeksirani podaci dolaze iz baze podataka ili u kojima postoji više virtualnih dokumenata u jednoj datoteci, poput ZIP arhive. Lucene omogućuje programerima da dostavljaju dokument indekseru putem a Stringili an InputStream, dopuštajući da se izvor podataka apstrahira iz podataka. Međutim, s ovim pristupom programer mora dostaviti odgovarajuće čitače podataka.
  • Kontrola indeksiranja: Neke tražilice mogu automatski puzati kroz stablo direktorija ili web stranicu kako bi pronašle dokumente za indeksiranje. Iako je to prikladno ako su vaši podaci već pohranjeni na ovaj način, indekseri temeljeni na indeksiranju često pružaju ograničenu fleksibilnost za programe koji zahtijevaju preciznu kontrolu nad indeksiranim dokumentima. Budući da Lucene djeluje prvenstveno u inkrementalnom načinu, aplikaciji omogućuje pronalaženje i preuzimanje dokumenata.
  • Formati datoteka: Neke tražilice mogu indeksirati samo tekst ili HTML dokumente; drugi podržavaju mehanizam filtra, koji nudi jednostavnu alternativu indeksiranju dokumenata za obradu teksta, SGML dokumenata i drugih formata datoteka. Lucen podržava takav mehanizam.
  • Označavanje sadržaja: neke tražilice dokument tretiraju kao jedan tok tokena; drugi dopuštaju specifikaciju više polja podataka unutar dokumenta, kao što su "predmet", "sažetak", "autor" i "tijelo". To dopušta semantički bogatije upite poput "autor sadrži Hamiltona I tijelo sadrži Ustav". Lucene podržava označavanje sadržaja tretiranjem dokumenata kao zbirki polja i podržava upite koji određuju koja polja treba pretraživati.
  • Zaustavljanje obrade riječi : Uobičajene riječi, poput "a", "i" i "the", dodaju malu vrijednost indeksu pretraživanja. No budući da su ove riječi tako česte, njihovo katalogiziranje znatno će pridonijeti vremenu indeksiranja i veličini indeksa. Većina pretraživača neće indeksirati određene riječi, koje se nazivaju zaustavnim riječima. Neki koriste popis zaustavnih riječi, dok drugi zaustavljaju riječi statistički. Lucene obrađuje zaustavne riječi općenitijim Analyzermehanizmom, koji će biti kasnije opisan, i nudi StopAnalyzerklasu koja uklanja zaustavne riječi iz ulaznog toka.
  • Stabljika: Korisnik često želi da se upit za jednu riječ podudara s drugim sličnim riječima. Na primjer, upit za "skok" vjerojatno bi se također trebao podudarati s riječima "skočio", "skakač" ili "skokovi". Smanjenje riječi svog korijena oblik naziva proizlazi . Lucene još uvijek ne primjenjuje korijen, ali lako biste mogli dodati matičnjak kroz sofisticiraniju Analyzerklasu.
  • Značajke upita: Tražilice podržavaju razne značajke upita. Neki podržavaju pune logičke upite; drugi podržavaju samo i upite. Neki vraćaju rezultat "relevantnosti" sa svakim pogotkom. Neki se mogu nositi s upitima za susjedstvo ili blizinu - "pretraživanje praćeno motorom" ili "Knicks blizu Celticsa" - drugi mogu pretraživati ​​samo s jednim ključnim riječima. Neki mogu pretraživati ​​više indeksa odjednom i objediniti rezultate dajući značajnu ocjenu relevantnosti. Lucene podržava širok raspon značajki upita, uključujući sve gore navedene. Međutim, Lucene ne podržava vrijedan Soundex ili upit "zvuči poput".
  • Istodobnost: Može li više korisnika istovremeno pretraživati ​​indeks? Može li korisnik pretraživati ​​indeks dok ga drugi ažurira? Lucene omogućuje korisnicima da pretražuju indeks transakcijski, čak i ako drugi korisnik istovremeno ažurira indeks.
  • Podrška koja nije na engleskom: Mnoge tražilice implicitno pretpostavljaju da je engleski ciljni jezik; to je vidljivo u područjima poput popisa zaustavnih riječi, algoritama koji proizlaze iz upotrebe i blizine kako bi se podudarali upiti za fraze. Kako Lucene unaprijed obrađuje ulazni tok kroz Analyzerklasu koju nudi programer, moguće je izvršiti filtriranje specifično za jezik.

Iako nipošto iscrpan, gornji popis nudi polazište za ocjenjivanje tražilice za određeni projekt. Neki alati za pretraživanje slabo odgovaraju određenim zadacima - razumijevanje zahtjeva vaše aplikacije može vam pomoći da odaberete pravi alat za posao.

Koristeći Lucene

Ilustrirat ću kako se koristi Lucene za stvaranje, popunjavanje i pretraživanje indeksa. Radi preglednosti, iz primjera programa izostavljeni su navodi za uvoz i rukovanje iznimkama. Na ovim ilustracijama pohranio sam indeks pretraživanja u datotečni sustav (indekse možete pohraniti bilo gdje, npr. U memoriju ili u bazu podataka). Datoteke koje se indeksiraju su jednostavne tekstualne datoteke. S Lucene također možete lako indeksirati druge formate dokumenata i dokumente koji nisu pohranjeni u datotekama.

Stvorite indeks

Jednostavni program CreateIndex.javastvara prazan indeks generirajući IndexWriterobjekt i upućujući ga da izgradi prazan indeks. U ovom primjeru naziv direktorija koji će pohraniti indeks naveden je u naredbenom retku.

javna klasa CreateIndex {// upotreba: CreateIndex direktorij indeksa public static void main (String [] args) baca iznimku {String indexPath = args [0]; Writer IndexWriter-a; // Indeks se stvara otvaranjem IndexWriter s argumentom // create postavljenim na true. pisac = novi IndexWriter (indexPath, null, true); pisac.close (); }}

Indeksirajte tekstualne dokumente

IndexFile.java shows how to add documents -- the files named on the command line -- to an index. For each file, IndexFiles creates a Document object, then calls IndexWriter.addDocument to add it to the index. From Lucene's point of view, a Document is a collection of fields that are name-value pairs. A Field can obtain its value from a String, for short fields, or an InputStream, for long fields. Using fields allows you to partition a document into separately searchable and indexable sections, and to associate metadata -- such as name, author, or modification date -- with a document. For example, when storing mail messages, you could put a message's subject, author, date, and body in separate fields, then build semantically richer queries like "subject contains Java AND author contains Gosling." In the code below, we store two fields in each Document: path, to identify the original file path so it can be retrieved later, and body, for the file's contents.

public class IndexFiles { // usage: IndexFiles index-path file . . . public static void main(String[] args) throws Exception { String indexPath = args[0]; IndexWriter writer; writer = new IndexWriter(indexPath, new SimpleAnalyzer(), false); for (int i=1; i