Търсачката Lucene: Мощна, гъвкава и безплатна

Не позволявайте на ниския номер на версията - 0,04 от август 2000 г. - да ви заблуждава. Търсачката Lucene е здрав, мощен и гъвкав набор от инструменти за търсене, готов да се справи с много често срещани проблеми при търсенето. И тъй като вече е достъпен под по-гъвкавия лиценз LGPL с отворен код, цената (безплатно!) Също е правилна.

Doug Cutting, опитен разработчик на инструменти за търсене и извличане на текст, създаде Lucene. Cutting е основният автор на търсачката V-Twin (част от усилията на операционната система Copland на Apple) и в момента е старши архитект в Excite. Той проектира Lucene, за да улесни добавянето на възможности за индексиране и търсене към широк спектър от приложения, включително:

  • Имейл с възможност за търсене: Приложението за електронна поща може да позволи на потребителите да търсят в архивирани съобщения и да добавят нови съобщения към индекса, когато пристигнат.
  • Онлайн търсене на документация: Четецът на документация - базиран на CD, базиран на уеб или вграден в приложението - може да позволи на потребителите да търсят онлайн документация или архивирани публикации.
  • Достъпни за търсене уеб страници: Уеб браузър или прокси сървър може да изгради лична търсачка, за да индексира всяка уеб страница, която потребителят е посетил, позволявайки на потребителите лесно да посещават отново страниците.
  • Търсене в уебсайт: Програма CGI може да позволи на потребителите да търсят във вашия уебсайт.
  • Търсене на съдържание: Приложението може да позволи на потребителя да търси запазени документи за конкретно съдържание; това може да бъде интегрирано в диалоговия прозорец Отворени документи.
  • Контрол на версиите и управление на съдържанието: Система за управление на документи може да индексира документи или версии на документи, така че те могат лесно да бъдат извлечени.
  • Емисии за новини и телеграфни услуги: Сървър за новини или реле може да индексира статии, когато пристигнат.

Разбира се, много търсачки могат да изпълняват повечето от тези функции, но малко инструменти за търсене с отворен код предлагат Lucene лесното използване, бързото внедряване и гъвкавостта.

За първи път използвах Lucene при разработването на Eyebrowse, инструмент с отворен код, базиран на Java, за каталогизиране и сърфиране в пощенски списъци. (Вижте Ресурси за връзка.) Основно изискване за Eyebrowse беше гъвкавата възможност за търсене и извличане на съобщения. Той изисква компонент за индексиране и търсене, който ефективно да актуализира базата на индексите при пристигането на нови съобщения, позволява на множество потребители да търсят и актуализират базата на индексите едновременно и да мащабира до архиви, съдържащи милиони съобщения.

Всяка друга търсачка с отворен код, която оцених, включително Swish-E, Glimpse, iSearch и libibex, беше по някакъв начин неподходяща за изискванията на Eyebrowse. Това би направило интеграцията проблематична и / или отнемаща време. С Lucene добавих индексиране и търсене към Eyebrowse за малко повече от половин ден, от първоначалното изтегляне до напълно работещия код! Това беше по-малко от една десета от времето за разработка, което бях предвидил, и даде по-тясно интегриран и богат на функции резултат от всеки друг инструмент за търсене, който считах.

Как работят търсачките

Създаването и поддържането на обърнат индекс е централният проблем при изграждането на ефективна търсачка за ключови думи. За да индексирате документ, първо трябва да го сканирате, за да създадете списък с публикации. Публикациите описват появата на дума в документ; те обикновено включват думата, идентификатор на документ и евентуално местоположението (местата) или честотата на думата в документа.

Ако мислите за проводките като кортежи на формуляра , набор от документи ще даде списък с публикации, сортирани по идентификатор на документа. Но за да намерите ефективно документите, които съдържат конкретни думи, вместо това трябва да сортирате публикациите по дума (или както по дума, така и по документ, което ще направи търсенето в много думи по-бързо). В този смисъл изграждането на индекс за търсене е основно проблем за сортиране. Индексът за търсене е списък с публикации, сортирани по дума.

Иновативно изпълнение

Повечето търсачки използват B-дървета, за да поддържат индекса; те са относително стабилни по отношение на вмъкването и имат добре поведени I / O характеристики (справките и вмъкванията са операции O (log n)). Lucene възприема малко по-различен подход: вместо да поддържа един индекс, той изгражда множество индексни сегменти и ги обединява периодично. За всеки нов документ, индексиран, Lucene създава нов индексен сегмент, но бързо обединява малки сегменти с по-големи - това поддържа общия брой сегменти малък, така че търсенията остават бързи. За да оптимизира индекса за бързо търсене, Lucene може да обедини всички сегменти в един, което е полезно за рядко актуализирани индекси. За да предотврати конфликти (или блокиране на режийни разходи) между четци на индекси и писатели, Lucene никога не модифицира сегменти на място, а само създава нови. Когато обединявате сегменти,Lucene пише нов сегмент и изтрива старите - след като всички активни читатели са го затворили. Този подход се мащабира добре, предлага на разработчика висока степен на гъвкавост при търгуване на скоростта на индексиране за скорост на търсене и има желани I / O характеристики както за сливане, така и за търсене.

Индексният сегмент на Lucene се състои от няколко файла:

  • Речников индекс, съдържащ по един запис за всеки 100 записа в речника
  • Речник, съдържащ по един запис за всяка уникална дума
  • Файл за проводки, съдържащ запис за всяко публикуване

Тъй като Lucene никога не актуализира сегменти на място, те могат да се съхраняват в плоски файлове, вместо в сложни B-дървета. За бързо извличане речниковият индекс съдържа отмествания във файла на речника, а речникът съдържа отмествания във файла за осчетоводяване. Lucene също така изпълнява различни трикове за компресиране на речника и публикуването на файлове - като по този начин намалява дисковите I / O - без да причинява значителни режийни разходи на процесора.

Оценка на търсачките

Други широко използвани търсачки с отворен код включват Swish-E, Glimpse, libibex, freeWAIS и iSearch. Както всеки софтуерен пакет, всеки е оптимизиран за използване в определени ситуации; често е трудно да се разположат тези инструменти извън предвидените им домейни. Помислете за следните функции, когато оценявате търсачката:

  • Инкрементално спрямо пакетно индексиране: Някои търсачки поддържат само индексиране на партиди; след като създадат индекс за набор от документи, добавянето на нови документи става трудно без повторно индексиране на всички документи. Инкременталното индексиране позволява лесно добавяне на документи към съществуващ индекс. За някои приложения, като тези, които обработват емисии с данни на живо, инкременталното индексиране е от решаващо значение. Lucene поддържа и двата вида индексиране.
  • Източници на данни: Много търсачки могат да индексират само файлове или уеб страници. Това затруднява приложенията, при които индексираните данни идват от база данни или където в един файл съществуват множество виртуални документи, като ZIP архив. Lucene позволява на разработчиците да доставят документа на индексатора чрез a Stringили an InputStream, което позволява източникът на данни да бъде абстрахиран от данните. При този подход обаче разработчикът трябва да предостави подходящите четци за данните.
  • Контрол върху индексирането: Някои търсачки могат автоматично да пълзят през дърво на директории или уебсайт, за да намерят документи за индексиране. Въпреки че това е удобно, ако вашите данни вече се съхраняват по този начин, индексаторите, базирани на обхождане, често осигуряват ограничена гъвкавост за приложения, които изискват фин контрол върху индексираните документи. Тъй като Lucene работи предимно в инкрементален режим, той позволява на приложението да намира и извлича документи.
  • Файлови формати: Някои търсачки могат да индексират само текст или HTML документи; други поддържат механизъм за филтриране, който предлага проста алтернатива на индексирането на текстообработващи документи, SGML документи и други файлови формати. Луцен поддържа такъв механизъм.
  • Маркиране на съдържание: Някои търсачки третират документ като единичен поток от символи; други позволяват спецификацията на множество полета с данни в даден документ, като „предмет“, „резюме“, „автор“ и „тяло“. Това позволява семантично по-богати заявки като „авторът съдържа Хамилтън И тялото съдържа конституция“. Lucene поддържа маркиране на съдържание, като третира документите като колекции от полета и поддържа заявки, които посочват в кои полета да се търси.
  • Спиране на обработката на думи: Често използвани думи, като „a“, „и“ и „the“, добавят малка стойност към индекса за търсене. Но тъй като тези думи са толкова често срещани, каталогизирането им ще допринесе значително за времето за индексиране и размера на индекса. Повечето търсачки няма да индексират определени думи, наречени стоп думи. Някои използват списък със стоп думи, докато други избират стоп думи статистически. Lucene обработва стоп думи с по-общия Analyzerмеханизъм, който ще бъде описан по-късно, и предоставя StopAnalyzerкласа, който елиминира стоп думите от входния поток.
  • Зареждане: Често потребителят желае заявка за една дума да съвпада с други подобни думи. Например, заявка за „скок“ вероятно също трябва да съвпада с думите „скочи“, „джъмпер“ или „скокове“. Намаляването на думата до нейната коренна форма се нарича произтичане . Lucene все още не прилага стеминг, но можете лесно да добавите stemmer чрез по-сложен Analyzerклас.
  • Характеристики на заявката: Търсачките поддържат различни функции за заявки. Някои поддържат пълни булеви заявки; други поддържат само и заявки. Някои връщат резултат „уместност“ при всяко попадение. Някои могат да се справят със заявки за съседство или близост - „търсене, последвано от двигател“ или „Никс близо до Селтикс“ - други могат да търсят само по отделни ключови думи. Някои могат да търсят в няколко индекса наведнъж и да обединяват резултатите, за да дадат значима оценка на значимостта. Lucene поддържа широк спектър от функции за заявки, включително всички изброени по-горе. Lucene обаче не поддържа ценната заявка Soundex или „звучи като“.
  • Паралелност: Могат ли няколко потребители да търсят индекс едновременно? Може ли потребителят да търси индекс, докато друг го актуализира? Lucene позволява на потребителите да търсят индекс транзакционно, дори ако друг потребител едновременно актуализира индекса.
  • Неанглийска поддръжка: Много търсачки предполагат неявно, че английският е целевият език; това е очевидно в области като списъци със спирки на думи, алгоритми, произтичащи от това, и използването на близост за съвпадение на фразови заявки. Тъй като Lucene предварително обработва входния поток през Analyzerкласа, предоставен от разработчика, е възможно да се извърши специфично за езика филтриране.

Въпреки че в никакъв случай не е изчерпателен, горният списък предлага отправна точка за оценка на търсачката за конкретен проект. Някои инструменти за търсене не са подходящи за определени задачи - разбирането на изискванията на вашето приложение може да ви помогне да изберете правилния инструмент за работата.

Използване на луцен

Ще илюстрирам как да използвам Lucene за създаване, попълване и търсене на индекс. За по-голяма яснота импортираните изявления и обработката на изключения са пропуснати от примерните програми. В тези илюстрации съм съхранил индекса за търсене във файловата система (можете да съхранявате индекси навсякъде, например в паметта или в база данни). Индексираните файлове са прости текстови файлове. С Lucene можете също лесно да индексирате други формати на документи и документи, които не се съхраняват във файлове.

Създайте индекс

The simple program CreateIndex.java creates an empty index by generating an IndexWriter object and instructing it to build an empty index. In this example, the name of the directory that will store the index is specified on the command line.

public class CreateIndex { // usage: CreateIndex index-directory public static void main(String[] args) throws Exception { String indexPath = args[0]; IndexWriter writer; // An index is created by opening an IndexWriter with the // create argument set to true. writer = new IndexWriter(indexPath, null, true); writer.close(); } } 

Index text documents

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