Programmering

Lucene-søkemotoren: Kraftig, fleksibel og gratis

Ikke la det lave versjonsnummeret - 0,04 per august 2000 - lure deg. Lucene-søkemotoren er en robust, kraftig og fleksibel søkeverktøysett, klar til å takle mange vanlige søkeproblemer. Og siden den nå er tilgjengelig under den mer fleksible LGPL open source-lisensen, er prisen (gratis!) Også riktig.

Doug Cutting, en erfaren utvikler av verktøy for tekstsøking og gjenfinning, opprettet Lucene. Cutting er den viktigste forfatteren av V-Twin-søkemotoren (en del av Apples Copland-operativsysteminnsats) og er for tiden seniorarkitekt hos Excite. Han designet Lucene for å gjøre det enkelt å legge til indeksering og søkefunksjon i et bredt spekter av applikasjoner, inkludert:

  • Søkbar e-post: Et e-postprogram kan la brukere søke i arkiverte meldinger og legge til nye meldinger i indeksen når de kommer.
  • Online dokumentasjonssøk: En dokumentasjonsleser - CD-basert, nettbasert eller innebygd i applikasjonen - kan la brukere søke online dokumentasjon eller arkiverte publikasjoner.
  • Søkbare nettsider: En nettleser eller proxy-server kan bygge en personlig søkemotor for å indeksere hver webside en bruker har besøkt, slik at brukerne enkelt kan besøke sider.
  • Nettstedsøk: Et CGI-program kan la brukere søke på nettstedet ditt.
  • Innholdssøk: Et program kan la brukeren søke i lagrede dokumenter etter spesifikt innhold; dette kan integreres i dialogboksen Åpne dokument.
  • Versjonskontroll og innholdshåndtering: Et dokumenthåndteringssystem kan indeksere dokumenter eller dokumentversjoner, slik at de lett kan hentes.
  • Nyheter og trådtjenester feeds: En nyhetsserver eller et stafett kan indeksere artikler når de kommer.

Selvfølgelig kan mange søkemotorer utføre de fleste av disse funksjonene, men få verktøy for åpen kildekode tilbyr Lucenes brukervennlighet, rask implementering og fleksibilitet.

Jeg brukte Lucene først da jeg utviklet Eyebrowse, et åpen kildekode Java-basert verktøy for katalogisering og surfing av adresselister. (Se Ressurser for en lenke.) Et kjernekrav for Eyebrowse var fleksibel meldingssøk og gjenfinning. Det krevde en indekserings- og søkekomponent som effektivt ville oppdatere indeksbasen når nye meldinger kom, tillate flere brukere å søke og oppdatere indeksbasen samtidig og skalere til arkiver som inneholder millioner av meldinger.

Hver annen åpen kildekode-søkemotor jeg evaluerte, inkludert Swish-E, Glimpse, iSearch og libibex, var dårlig tilpasset Eyebrowses krav på en eller annen måte. Dette ville ha gjort integrering problematisk og / eller tidkrevende. Med Lucene la jeg til indeksering og søk til Eyebrowser på litt mer enn en halv dag, fra første nedlasting til fullstendig fungerende kode! Dette var mindre enn en tidel av utviklingstiden jeg hadde budsjettert med, og ga et mer tett integrert og funksjonsrikt resultat enn noe annet søkeverktøy jeg vurderte.

Hvordan søkemotorer fungerer

Opprette og vedlikeholde en invertert indeks er det sentrale problemet når man bygger en effektiv søkeordmotor. For å indeksere et dokument, må du først skanne det for å lage en liste over innlegg. Innlegg beskriver forekomster av et ord i et dokument; de inkluderer vanligvis ordet, en dokument-ID og muligens plasseringen eller frekvensen av ordet i dokumentet.

Hvis du tenker på innleggene som formler på skjemaet , vil et sett med dokumenter gi en liste over innlegg sortert etter dokument-ID. Men for å effektivt finne dokumenter som inneholder bestemte ord, bør du i stedet sortere innleggene etter ord (eller etter både ord og dokument, noe som vil gjøre flerspråkssøk raskere). Slik sett er å bygge en søkeindeks i utgangspunktet et sorteringsproblem. Søkeindeksen er en liste over innlegg sortert etter ord.

En innovativ implementering

De fleste søkemotorer bruker B-trær for å opprettholde indeksen; de er relativt stabile med hensyn til innsetting og har veloppførte I / O-egenskaper (oppslag og innsetting er O (log n) -operasjoner). Lucene tar en litt annen tilnærming: i stedet for å opprettholde en enkelt indeks, bygger den flere indekssegmenter og slår dem sammen regelmessig. For hvert nye dokument som er indeksert, oppretter Lucene et nytt indeksegment, men det smelter raskt sammen små segmenter med større - dette holder det totale antallet segmenter lite, slik at søk fortsatt er raske. For å optimalisere indeksen for rask søk, kan Lucene slå sammen alle segmentene i ett, noe som er nyttig for sjeldent oppdaterte indekser. For å forhindre konflikter (eller låse overhead) mellom indekslesere og forfattere, endrer Lucene aldri segmenter på plass, det skaper bare nye. Ved sammenslåing av segmenter skriver Lucene et nytt segment og sletter de gamle - etter at aktive lesere har lukket det. Denne tilnærmingen skalerer seg godt, gir utvikleren en høy grad av fleksibilitet i å avveie indekseringshastighet for søkehastighet, og har ønskelige I / O-egenskaper for både sammenslåing og søk.

Et Lucene indeks segment består av flere filer:

  • En ordbokindeks som inneholder en oppføring for hver 100 oppføringer i ordboken
  • En ordbok som inneholder en oppføring for hvert unike ord
  • En innleggingsfil som inneholder en oppføring for hvert innlegg

Siden Lucene aldri oppdaterer segmenter på plass, kan de lagres i flate filer i stedet for kompliserte B-trær. For rask henting inneholder ordbokindeksen forskyvninger i ordboksfilen, og ordboken holder forskyvninger i innleggingsfilen. Lucene implementerer også en rekke triks for å komprimere ordboken og legge ut filer - og dermed redusere disk I / O - uten å pådra seg betydelig CPU-overhead.

Evaluering av søkemotorer

Andre mye brukte open source-søkemotorer inkluderer Swish-E, Glimpse, libibex, freeWAIS og iSearch. Som enhver programvarepakke, er hver optimalisert for bruk i spesielle situasjoner; det er ofte vanskelig å distribuere disse verktøyene utenfor de tiltenkte domenene. Vurder følgende funksjoner når du vurderer en søkemotor:

  • Inkrementell versus batch-indeksering: Noen søkemotorer støtter bare batchindeksering; når de oppretter en indeks for et sett med dokumenter, blir det vanskelig å legge til nye dokumenter uten å indeksere alle dokumentene på nytt. Inkrementell indeksering gjør det enkelt å legge til dokumenter i en eksisterende indeks. For noen applikasjoner, som de som håndterer live datastrømmer, er trinnvis indeksering kritisk. Lucene støtter begge typer indeksering.
  • Datakilder: Mange søkemotorer kan bare indeksere filer eller websider. Dette hindrer applikasjoner der indekserte data kommer fra en database, eller hvor det eksisterer flere virtuelle dokumenter i en enkelt fil, for eksempel et ZIP-arkiv. Lucene lar utviklere levere dokumentet til indeksøren gjennom en String eller en InputStream, slik at datakilden kan trekkes ut av dataene. Imidlertid, med denne tilnærmingen, må utvikleren levere de aktuelle leserne for dataene.
  • Indekseringskontroll: Noen søkemotorer kan automatisk krype gjennom et katalogtre eller et nettsted for å finne dokumenter å indeksere. Selv om dette er praktisk hvis dataene dine allerede er lagret på denne måten, gir crawlerbaserte indekserer ofte begrenset fleksibilitet for applikasjoner som krever finkornet kontroll over de indekserte dokumentene. Siden Lucene primært opererer i inkrementell modus, lar den applikasjonen finne og hente dokumenter.
  • Filformater: Noen søkemotorer kan bare indeksere tekst eller HTML-dokumenter; andre støtter en filtermekanisme, som tilbyr et enkelt alternativ til indeksering av tekstbehandlingsdokumenter, SGML-dokumenter og andre filformater. Lucene støtter en slik mekanisme.
  • Innholdsmerking: Noen søkemotorer behandler et dokument som en enkelt strøm av tokens; andre tillater spesifikasjon av flere datafelter i et dokument, for eksempel "emne", "abstrakt", "forfatter" og "kropp". Dette tillater semantisk rikere spørsmål som "forfatter inneholder Hamilton OG kropp inneholder Constitution. "Lucene støtter innholdsmerking ved å behandle dokumenter som feltsamlinger, og støtter spørsmål som spesifiserer hvilke felt du vil søke i.
  • Stopp-tekstbehandling: Vanlige ord, for eksempel "a", "og" og "the", gir liten verdi til en søkeindeks. Men siden disse ordene er så vanlige, vil katalogisering av dem bidra betydelig til indekseringstid og indeksstørrelse. De fleste søkemotorer vil ikke indeksere bestemte ord, kalt stopp ord. Noen bruker en liste over stoppord, mens andre velger stoppord statistisk. Lucene håndterer stoppord med det mer generelle Analysator mekanisme, som skal beskrives senere, og gir StopAnalyzer klasse, som eliminerer stoppord fra inngangsstrømmen.
  • Stemming: Ofte ønsker en bruker et spørsmål om et ord for å matche andre lignende ord. For eksempel bør et spørsmål om "hopp" sannsynligvis også matche ordene "hoppet", "hopper" eller "hopp." Å redusere et ord til rotformen kalles stemming. Lucene implementerer ikke stemming ennå, men du kan enkelt legge til en stemme gjennom en mer sofistikert Analysator klasse.
  • Spørringsfunksjoner: Søkemotorer støtter en rekke søkefunksjoner. Noen støtter fulle boolske spørsmål; andre støtter bare og spørsmål. Noen gir "relevans" -poeng for hvert treff. Noen kan håndtere nærhet eller nærhet - "søk etterfulgt av motor "eller" Knicks nær Celtics "- andre kan bare søke på enkle nøkkelord. Noen kan søke i flere indekser samtidig og slå sammen resultatene for å gi en meningsfull relevanspoeng. Lucene støtter et bredt spekter av søkefunksjoner, inkludert alle de som er oppført ovenfor. støtter ikke det verdifulle spørsmålet Soundex eller "høres ut".
  • Samtidighet: Kan flere brukere søke i en indeks samtidig? Kan en bruker søke i en indeks mens en annen oppdaterer den? Lucene lar brukerne søke i en indeks transaksjonsmessig, selv om en annen bruker samtidig oppdaterer indeksen.
  • Ikke-engelsk støtte: Mange søkemotorer antar implisitt at engelsk er målspråket; Dette er tydelig i områder som stoppordlister, stemmealgoritmer og bruk av nærhet for å matche setningsspørsmål. Når Lucene behandler inngangsstrømmen gjennom Analysator klasse gitt av utvikleren, er det mulig å utføre språkspesifikk filtrering.

Selv om det på ingen måte er uttømmende, gir listen ovenfor et utgangspunkt for å evaluere en søkemotor for et bestemt prosjekt. Noen søkeverktøy passer dårlig til visse oppgaver - å forstå applikasjonens krav kan hjelpe deg med å velge riktig verktøy for jobben.

Bruker Lucene

Jeg vil illustrere hvordan du bruker Lucene til å opprette, fylle ut og søke i en indeks. For klarhetens skyld er importuttalelser og unntakshåndtering utelatt fra prøveprogrammene. I disse illustrasjonene har jeg lagret søkeindeksen i filsystemet (du kan lagre indekser hvor som helst, f.eks. I minnet eller i en database). Filene som indekseres er enkle tekstfiler. Med Lucene kan du også enkelt indeksere andre dokumentformater og dokumenter som ikke er lagret i filer.

Lag en indeks

Det enkle programmet CreateIndex.java oppretter en tom indeks ved å generere en IndexWriter objekt og instruere den om å bygge en tom indeks. I dette eksemplet er navnet på katalogen som vil lagre indeksen spesifisert på kommandolinjen.

offentlig klasse CreateIndex {// bruk: CreateIndex indekskatalog offentlig statisk ugyldig hoved (String [] args) kaster Unntak {String indexPath = args [0]; IndexWriter forfatter; // En indeks opprettes ved å åpne en IndexWriter med // create-argumentet satt til true. skribent = ny IndexWriter (indexPath, null, true); writer.close (); }} 

Indeksere tekstdokumenter

IndexFile.java viser hvordan du legger til dokumenter - filene navngitt på kommandolinjen - til en indeks. For hver fil, IndexFiles skaper en Dokument objektet, deretter ringer IndexWriter.addDocument for å legge den til i indeksen. Fra Lucene synspunkt, a Dokument er en samling felt som er navn-verdipar. EN Felt kan få verdien fra en String, for korte felt, eller en InputStream, for lange felt. Ved å bruke felt kan du dele et dokument i seksjoner som kan søkes og indekseres separat, og knytte metadata - for eksempel navn, forfatter eller endringsdato - til et dokument. Når du for eksempel lagrer e-postmeldinger, kan du legge emnet, forfatteren, datoen og brødteksten til en melding i separate felt, og deretter lage semantisk rikere spørsmål som "emne inneholder Java OG forfatter inneholder Gosling. "I koden nedenfor lagrer vi to felt i hver Dokument: sti, for å identifisere den originale filbanen slik at den kan hentes senere, og kropp, for filens innhold.

offentlig klasse IndexFiles {// bruk: IndexFiles indekssti-fil. . . offentlig statisk ugyldig hoved (String [] args) kaster Unntak {String indexPath = args [0]; IndexWriter forfatter; skribent = ny IndexWriter (indexPath, ny SimpleAnalyzer (), false); for (int i = 1; i
$config[zx-auto] not found$config[zx-overlay] not found