Ohjelmointi

Lucene-hakukone: Tehokas, joustava ja ilmainen

Älä anna matalan versionumeron - 0,04 elokuusta 2000 - huijata sinua. Lucene-hakukone on vankka, tehokas ja joustava hakutyökalupaketti, joka on valmis ratkaisemaan monia yleisiä hakuongelmia. Ja koska se on nyt saatavana joustavammalla LGPL: n avoimen lähdekoodin lisenssillä, myös hinta (ilmainen!) On oikea.

Doug Cutting, kokenut tekstihaku- ja hakutyökalujen kehittäjä, loi Lucenen. Cutting on V-Twin-hakukoneen pääasiallinen kirjoittaja (osa Applen Copland-käyttöjärjestelmän työtä) ja on tällä hetkellä Excite: n vanhempi arkkitehti. Hän suunnitteli Lucenen helpottamaan indeksoinnin ja hakukyvyn lisäämistä moniin sovelluksiin, mukaan lukien:

  • Haettava sähköposti: Sähköpostisovellus voi antaa käyttäjien etsiä arkistoituja viestejä ja lisätä uusia viestejä hakemistoon saapuessaan.
  • Online-dokumenttihaku: Dokumentaationlukija - CD-pohjainen, verkkopohjainen tai upotettu sovellukseen - voi antaa käyttäjien etsiä online-dokumentaatiota tai arkistoituja julkaisuja.
  • Haettavat verkkosivut: Web-selain tai välityspalvelin voisi rakentaa henkilökohtaisen hakukoneen indeksoimaan jokaisen käyttäjän vieraileman verkkosivun, jolloin käyttäjät voivat helposti vierailla sivuilla.
  • Verkkosivujen haku: CGI-ohjelma voi antaa käyttäjien hakea verkkosivustoltasi.
  • Sisältöhaku: Sovellus voi antaa käyttäjän etsiä tallennettuja asiakirjoja tietyn sisällön suhteen; tämä voidaan integroida Open Document -valintaikkunaan.
  • Versioiden hallinta ja sisällön hallinta: Asiakirjojen hallintajärjestelmä voi indeksoida asiakirjoja tai asiakirjan versioita, jotta ne voidaan helposti hakea.
  • Uutiset ja langalliset palvelut: Uutispalvelin tai -välitin voisi indeksoida artikkeleita saapuessaan.

Tietysti monet hakukoneet voisivat suorittaa suurimman osan näistä toiminnoista, mutta harvat avoimen lähdekoodin hakutyökalut tarjoavat Lucenen helppokäyttöisyyden, nopean toteutuksen ja joustavuuden.

Käytin ensin Lucenea kehittäessäni Eyebrowse-ohjelmistoa, avoimen lähdekoodin Java-pohjaista työkalua postituslistojen luettelointiin ja selaamiseen. (Katso linkki Resursseista.) Kulmakarvan perusedellytys oli joustava viestien haku ja haku. Se vaati indeksointi- ja hakukomponenttia, joka päivittäisi hakemistokannan tehokkaasti uusien viestien saapuessa, antaisi useille käyttäjille mahdollisuuden hakea ja päivittää hakemistopohjaa samanaikaisesti ja skaalautui miljooniin viesteihin.

Kaikki muut arvioimani avoimen lähdekoodin hakukoneet, mukaan lukien Swish-E, Glimpse, iSearch ja libibex, sopivat jollain tavalla huonosti kulmakarvojen vaatimuksiin. Tämä olisi tehnyt integraatiosta ongelmallista ja / tai aikaa vievää. Lucenen kanssa lisäsin indeksoinnin ja hakemisen Kulmakarvaan hieman yli puolessa päivässä alkuperäisestä latauksesta täysin toimivaan koodiin! Tämä oli alle kymmenesosa budjetoimastani kehitysajasta ja antoi tiukemmin integroidun ja monipuolisen tuloksen kuin mikään muu harkitsemani hakutyökalu.

Kuinka hakukoneet toimivat

Luodaan ja ylläpidetään käänteinen indeksi on keskeinen ongelma tehokkaan avainsanahakukoneen rakentamisessa. Jos haluat indeksoida asiakirjan, sinun on ensin skannattava se tuottamaan luettelo lähettämistä. Lähetykset kuvaavat sanan esiintymiä asiakirjassa; ne sisältävät yleensä sanan, asiakirjan tunnuksen ja mahdollisesti sanan sijainnin (paikat) tai taajuuden asiakirjassa.

Jos ajattelet lähetyksiä lomakejoukkoina , joukko asiakirjoja antaa luettelon postituksista, jotka on lajiteltu asiakirjan tunnuksen mukaan. Mutta tiettyjä sanoja sisältävien asiakirjojen löytämiseksi sinun tulisi sen sijaan lajitella ilmoitukset sanan (tai sekä sanan että asiakirjan mukaan, mikä tekee monisanahakuista nopeammin). Tässä mielessä hakuindeksin luominen on pohjimmiltaan lajitteluongelma. Hakuhakemisto on luettelo viesteistä lajiteltu sanan mukaan.

Innovatiivinen toteutus

Useimmat hakukoneet käyttävät B-puita indeksin ylläpitämiseen; ne ovat suhteellisen vakaita lisäyksen suhteen ja niillä on hyvin käytettävät I / O-ominaisuudet (hakut ja lisäykset ovat O (log n) -operaatioita). Lucene käyttää hieman erilaista lähestymistapaa: yhden indeksin ylläpitämisen sijaan se rakentaa useita indeksisegmenttejä ja yhdistää ne säännöllisesti. Jokaiselle indeksoidulle uudelle asiakirjalle Lucene luo uuden hakemistosegmentin, mutta se sulauttaa nopeasti pienet segmentit suurempiin - tämä pitää segmenttien kokonaismäärän pienenä, joten haut pysyvät nopeasti. Hakemiston optimoimiseksi nopeaa hakua varten Lucene voi yhdistää kaikki segmentit yhdeksi, mikä on hyödyllistä harvoin päivitettävissä hakemistoissa. Hakemistonlukijoiden ja kirjoittajien välisten ristiriitojen (tai lukituksen estämiseksi) estämiseksi Lucene ei koskaan muuta segmenttejä paikalleen, vaan luo vain uusia. Kun segmentit yhdistetään, Lucene kirjoittaa uuden segmentin ja poistaa vanhat segmentit, kun kaikki aktiiviset lukijat ovat sulkeneet sen. Tämä lähestymistapa skaalautuu hyvin, tarjoaa kehittäjälle suuren joustavuuden indeksointinopeuden kaupan pitämisessä hakunopeutta varten ja sillä on toivottavat I / O-ominaisuudet sekä yhdistämiseen että etsimiseen.

Lucene-hakemistosegmentti koostuu useista tiedostoista:

  • Sanakirjahakemisto, joka sisältää yhden merkinnän sanakirjan jokaisesta 100 merkinnästä
  • Sanakirja, joka sisältää yhden merkinnän kutakin ainutlaatuista sanaa varten
  • Lähetystiedosto, joka sisältää merkinnän kustakin lähetyksestä

Koska Lucene ei koskaan päivitä segmenttejä paikallaan, ne voidaan tallentaa tasaisiksi tiedostoiksi monimutkaisten B-puiden sijaan. Nopeaa hakua varten sanakirjahakemisto sisältää siirtymiä sanakirjatiedostoon ja sanakirja pitää siirtoja lähetystiedostoon. Lucene toteuttaa myös useita temppuja sanakirjan pakkaamiseen ja tiedostojen lähettämiseen - mikä vähentää levyn I / O-tilaa - aiheuttamatta merkittäviä suorittimen lisäkustannuksia.

Hakukoneiden arviointi

Muita laajalti käytettyjä avoimen lähdekoodin hakukoneita ovat Swish-E, Glimpse, libibex, freeWAIS ja iSearch. Kuten kaikki ohjelmistopaketit, kukin on optimoitu käytettäväksi tietyissä tilanteissa; Näiden työkalujen käyttöönotto niiden tarkoitetun toimialueen ulkopuolella on usein vaikeaa. Harkitse seuraavia ominaisuuksia arvioidessasi hakukonetta:

  • Inkrementaalinen verrattuna eräindeksiin: Jotkut hakukoneet tukevat vain eräindeksointia; Kun he luovat hakemiston joukolle asiakirjoja, uusien asiakirjojen lisääminen on vaikeaa indeksoimatta kaikkia asiakirjoja uudelleen. Inkrementaalinen indeksointi mahdollistaa asiakirjojen helpon lisäämisen olemassa olevaan hakemistoon. Joissakin sovelluksissa, kuten reaaliaikaisia ​​datasyötteitä käsittelevissä sovelluksissa, asteittainen indeksointi on kriittistä. Lucene tukee molempia indeksointityyppejä.
  • Tietolähteet: Monet hakukoneet voivat indeksoida vain tiedostoja tai verkkosivuja. Tämä haittaa sovelluksia, joissa indeksoidut tiedot tulevat tietokannasta tai joissa yhdessä tiedostossa on useita virtuaalisia asiakirjoja, kuten ZIP-arkisto. Lucene antaa kehittäjien toimittaa asiakirjan hakemistolle a Merkkijono tai an InputStream, jolloin tietolähde voidaan erottaa tiedoista. Tällä lähestymistavalla kehittäjän on kuitenkin toimitettava asianmukaiset lukijat tiedoille.
  • Indeksoinnin hallinta: Jotkut hakukoneet voivat indeksoida hakemistopuun tai verkkosivuston automaattisesti löytääksesi indeksoitavia asiakirjoja. Vaikka tämä on kätevää, jos tietosi on jo tallennettu tällä tavalla, indeksointipohjaiset indeksoijat tarjoavat usein rajoitetun joustavuuden sovelluksille, jotka edellyttävät indeksoitujen asiakirjojen tarkkaa hallintaa. Koska Lucene toimii ensisijaisesti inkrementaalitilassa, se antaa sovelluksen löytää ja hakea asiakirjoja.
  • Tiedostomuodot: Jotkut hakukoneet voivat indeksoida vain teksti- tai HTML-asiakirjoja. toiset tukevat suodatusmekanismia, joka tarjoaa yksinkertaisen vaihtoehdon tekstinkäsittelydokumenttien, SGML-asiakirjojen ja muiden tiedostomuotojen indeksoinnille. Lucene tukee tällaista mekanismia.
  • Sisällön merkitseminen: Jotkut hakukoneet käsittelevät asiakirjaa yhtenä virtana tunnuksia; toiset sallivat useiden tietokenttien määrittelyn asiakirjassa, kuten "aihe", "tiivistelmä", "tekijä" ja "runko". Tämä sallii semanttisesti rikkaammat kyselyt, kuten "kirjailija" sisältää Hamilton JA runko sisältää Constitution. "Lucene tukee sisällön merkitsemistä käsittelemällä asiakirjoja kenttäkokoelmina ja tukee kyselyjä, jotka määrittelevät hakukentät.
  • Stop-tekstinkäsittely: Yleiset sanat, kuten "a", "" ja "ja", "lisäävät vain vähän arvoa hakuhakemistoon. Mutta koska nämä sanat ovat niin yleisiä, niiden luettelointi lisää huomattavasti indeksointiaikaa ja indeksin kokoa. Useimmat hakukoneet eivät indeksoi tiettyjä sanoja lopeta sanat. Jotkut käyttävät lopetussanaluetteloa, kun taas toiset valitsevat pysäytyssanat tilastollisesti. Lucene käsittelee pysäytyssanoja yleisemmällä Analysaattori mekanismi, joka kuvataan myöhemmin, ja tarjoaa StopAnalyzer luokka, joka poistaa pysäytyssanat tulovirrasta.
  • Stemming: Usein käyttäjä haluaa yhden sanan kyselyn vastaavan muita vastaavia sanoja. Esimerkiksi "hyppy" -hakun tulisi todennäköisesti vastata myös sanoja "hyppäsi", "hyppääjä" tai "hyppy". Sanan pelkistämistä juurimuotoon kutsutaan stemming. Lucene ei vielä toteuta stemmingiä, mutta voit helposti lisätä rungon hienostuneemman kautta Analysaattori luokassa.
  • Kyselyn ominaisuudet: Hakukoneet tukevat erilaisia ​​kyselyominaisuuksia. Jotkut tukevat täydellisiä Boolen-kyselyjä; toiset vain tukevat ja kyselyt. Jotkut palauttavat "osuvuus" -pisteet jokaisen osuman kanssa. Jotkut voivat käsitellä läheisyys- tai läheisyyskyselyjä - "haku" jonka jälkeen moottori "tai" Knicks lähellä Celtics "- toiset voivat tehdä hakuja vain yksittäisillä avainsanoilla. Jotkut voivat hakea useita hakemistoja kerralla ja yhdistää tulokset antaakseen mielekkään relevanssipisteen. Lucene tukee monenlaisia ​​kyselyominaisuuksia, mukaan lukien kaikki edellä luetellut. Lucene kuitenkin tekee eivät tue arvokasta Soundex- tai "kuulostaa" -kyselyä.
  • Samanaikaisuus: Voivatko useat käyttäjät hakea hakemistosta samanaikaisesti? Voiko käyttäjä hakea hakemistosta, kun toinen päivittää sitä? Lucene antaa käyttäjille mahdollisuuden hakea hakemistoa transaktiolla, vaikka toinen käyttäjä päivittäisi hakemistoa samanaikaisesti.
  • Muu kuin englanninkielinen tuki: Monet hakukoneet olettavat implisiittisesti, että englanti on kohdekieli; tämä on ilmeistä esimerkiksi pysäytyssanaluetteloissa, alkavilla algoritmeilla ja läheisyyden avulla lausehakujen vastaamiseksi. Kun Lucene esikäsittelee syötevirran Analysaattori kehittäjän tarjoama luokka, on mahdollista suorittaa kielikohtainen suodatus.

Vaikka yllä oleva luettelo ei suinkaan ole tyhjentävä, se tarjoaa lähtökohdan tietyn projektin hakukoneen arvioinnille. Jotkut hakutyökalut soveltuvat huonosti tiettyihin tehtäviin - sovelluksesi vaatimusten ymmärtäminen voi auttaa valitsemaan työhön oikean työkalun.

Lucenen käyttö

Havainnollistan kuinka Lucenen avulla luodaan, täytetään ja haetaan hakemistoa. Selkeyden vuoksi tuontilausekkeet ja poikkeusten käsittely on jätetty pois esimerkkiohjelmista. Näihin kuviin olen tallentanut hakuhakemiston tiedostojärjestelmään (indeksit voidaan tallentaa mihin tahansa, esim. Muistiin tai tietokantaan). Indeksoitavat tiedostot ovat yksinkertaisia ​​tekstitiedostoja. Lucenen avulla voit myös helposti indeksoida muita tiedostomuotoja ja tiedostoja, joita ei ole tallennettu tiedostoihin.

Luo hakemisto

Yksinkertainen ohjelma CreateIndex.java luo tyhjän hakemiston luomalla IndexWriter objektin ja käsketään sitä rakentamaan tyhjä hakemisto. Tässä esimerkissä hakemiston tallentavan hakemiston nimi määritetään komentorivillä.

public class CreateIndex {// käyttö: CreateIndex-hakemisto-hakemisto public static void main (String [] args) heittää poikkeuksen {String indexPath = args [0]; IndexWriter-kirjoittaja; // Hakemisto luodaan avaamalla IndexWriter siten, että // create-argumentti on tosi. kirjoittaja = new IndexWriter (indexPath, null, true); kirjailija.sulje (); }} 

Hakemistotekstit

IndexFile.java näyttää kuinka asiakirjat - komentorivillä nimetyt tiedostot - lisätään hakemistoon. Jokaiselle tiedostolle Hakemistotiedostot luo Asiakirja esine, sitten soittaa IndexWriter.addDocument lisätäksesi sen hakemistoon. Lucenen näkökulmasta a Asiakirja on kokoelma kenttiä, jotka ovat nimi-arvo-pareja. A Ala voi saada arvonsa a Merkkijono, lyhyille kentille tai InputStream, pitkille pelloille. Kenttien avulla voit jakaa asiakirjan erikseen haettaviin ja indeksoitaviin osioihin ja liittää metatiedot - kuten nimen, tekijän tai muokkauspäivän - asiakirjaan. Esimerkiksi sähköpostiviestejä tallennettaessa voit laittaa viestin aiheen, tekijän, päivämäärän ja tekstin erillisiin kenttiin ja sitten rakentaa semanttisesti rikkaampia kyselyjä, kuten "aihe" sisältää Java JA kirjailija sisältää Gosling. "Alla olevaan koodiin tallennamme kaksi kenttää kumpaankin Asiakirja: polku, tunnistaa alkuperäisen tiedostopolun, jotta se voidaan hakea myöhemmin, ja runko, tiedoston sisällöstä.

public class IndexFiles {// käyttö: IndexFiles hakemistopolun tiedosto. . . public static void main (String [] args) heittää poikkeuksen {String indexPath = args [0]; IndexWriter-kirjoittaja; kirjoittaja = new IndexWriter (indexPath, uusi SimpleAnalyzer (), väärä); varten (int i = 1; i