Матеріал по роботі з Apache Lucene і створення найпростішого нечіткого пошуку

Пост розрахований на початківців, на людей незнайомих з технологією Apache Lucene. У ньому немає матеріалу про те, як влаштований Apache Lucene всередині, які алгоритми, структури даних та методи використовувалися для створення фреймворка. Пост є навчальним матеріалом-тизером, написаним для того, щоб показати, як організувати найпростіший нечіткий пошук по тексту. В якості матеріалу для навчання наданий код на github, сам пост в якості документації і трохи даних для тестування пошукових запитів.



Введення

Докладно про бібліотеки Apache Lucene написано тут і тут. У статті будуть зустрічатися такі терміни як: запит, індексація, аналізатор, нечіткі збіги, токени, документи. Раджу спочатку прочитати ось цю статтю. У ній ці терміни описують в контексті фреймворку Elasticsearch, який базується на бібліотеках Apache Lucene. Тому базова термінологія і визначення збігаються.

Інструментарій

У статті описується використання Apache Lucene 5.4.1. Вихідний код доступний на github, в репозиторії є невеликий набір даних для тестування. По суті стаття є докладною документацією до коду в репозиторії. Почати «грати» з проектом можна з запуску тестів в класі BasicSearchExamplesTest.

Створення індексів

Проіндексувати документи можна за допомогою класу MessageIndexer. У ньому є метод index:

public void index(final Boolean create, List<Document> documents) throws IOException {
final Analyzer analyzer = new RussianAnalyzer();
index(create, documents, analyzer);
}


Він приймає на вхід змінну create та documents. Змінна create відповідає за поведінку індексування. Якщо вона дорівнює true, то індексатор буде створювати новий індекс навіть якщо індекс вже існував. Якщо false, то індекс буде оновлюватися.
Змінна documents це список об'єктів Document. Document це об'єкт індексації та пошуку. Він являє собою набір полів, кожне поле має ім'я і текстове значення. Для того щоб отримати список документів створено клас MessageToDocument. Його завдання-створювати Document використовуючи два строкових поля: body і title.

public static Document createWith(final String titleStr, final String bodyStr) {
final Document document = new Document();

final FieldType textIndexedType = new FieldType();
textIndexedType.setStored(true);
textIndexedType.setIndexOptions(IndexOptions.DOCS);
textIndexedType.setTokenized(true);

//index title
Field title = new Field("title", titleStr, textIndexedType);
//index body
Body Field = new Field("body", bodyStr, textIndexedType);

document.add(title);
document.add(body);
return document;
}


Зверніть увагу, що метод index за замовчуванням використовує RussianAnalyzerдоступний в бібліотеці lucene-analyzers-common.

Для того щоб пограти з створенням індексу перейдіть до класу MessageIndexerTest.

Пошук

Для демонстрації базових можливостей пошуку створений клас BasicSearchExamples. У ньому реалізовано два методи пошуку: простий пошук по токенам і нечіткий пошук. За простий пошук відповідають методи searchIndexWithTermQuery() та searchInBody(), за нечіткий пошук метод fuzzySearch().

У Lucene існує багато способів створити запит, але для простоти методи звичайного пошуку реалізовані тільки за допомогою класів QueryParser і TermQuery. Методи нечіткого пошуку використовують FuzzyQuery, яка залежить від одного важливого параметра: maxEdits. Цей параметр відповідає за нечіткість пошуку, подробиці тут. Поринути в розмаїття способів зробити запит можна тут.

Для того щоб пограти з пошуком перейдіть до класу BasicSearchExamplesTest

Завдання

Щоб грати з проектом було не нудно спробуйте виконати кілька завдань:
  • Зробіть інтерактивний консольний пошук. Пошук повинен показувати видачу і питати наступний запит.
  • Зараз пошук працює тільки з полем body. Зробіть так, щоб пошук працював по полях title і body одночасно.
  • Підрахуйте кількість проіндексованих слів (токенів)
  • Розширте модель Messageдодайте в неї регіон (region) і дату створення повідомлення (creationDate). Не забудьте додати нові поля для індексації в класі MessageToDocument. Додайте нові способи пошуку з фільтром по регіону і дату
  • Подивіться на клас запитів MoreLikeThisQuery. Спробуйте згрупувати всі документи по схожості використовуючи значення score.
  • Скачайте ось цей файл, в нього близько 5000 різних повідомлень. Перевірте, як працює угруповання, нові запити і фільтри.


Висновок

Перевага Apache Lucene в його простоті, високій швидкості роботи і низьких вимогах до ресурсів. Недолік у відсутності хорошої документації, особливо російською мовою. Проект дуже швидко розвивається, тому книги, туторіали та Q/A, якими забитий інтернет, давно втратили актуальність. Приміром, у мене пішло 4-5 днів тільки на те, щоб зрозуміти, як витягнути векторну модель TF-IDF з індексів Lucene. Сподіваюся, що цей пост приверне увагу фахівців до цієї проблеми нестачі інформації.

Для тих, хто хоче поринути у світ Apache Lucene раджу поглянути на документацію Elasticsearch. Багато речей там дуже добре описані, з посиланнями на авторитетні джерела і з прикладами.

Джерело: Хабрахабр
  • avatar
  • 0

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.