Lucene - это довольно большая тема с множеством классов и методов, и вы обычно не можете ее использовать, не понимая хотя бы некоторых основных понятий. Если вам нужна быстро доступная услуга, используйте Solr . Если вам нужен полный контроль над Lucene, продолжайте читать. Я расскажу о некоторых основных концепциях и классах Lucene, которые их представляют. (Для получения информации о том, как читать текстовые файлы в памяти, прочитайте, например, эту статью).
Что бы вы ни собирались делать в Lucene - индексирование или поиск - вам нужен анализатор. Цель анализатора состоит в том, чтобы токенизировать (разбить на слова) и поставить (получить базу слова) ваш вводимый текст. Он также выбрасывает наиболее часто встречающиеся слова, такие как «a», «the» и т. Д. Вы можете найти анализаторы для более чем 20 языков или использовать SnowballAnalyzer и передать язык в качестве параметра.
Чтобы создать экземпляр SnowballAnalyzer для английского языка, вам необходимо:
Analyzer analyzer = new SnowballAnalyzer(Version.LUCENE_30, "English");
Если вы собираетесь индексировать тексты на разных языках и хотите автоматически выбирать анализатор, вы можете использовать LanguageIdentifier tika .
Вам нужно где-то хранить свой индекс. Для этого есть две основные возможности: индекс в памяти, который легко попробовать, и дисковый индекс, который является наиболее распространенным.
Используйте любую из следующих 2 строк:
Directory directory = new RAMDirectory(); // RAM index storage
Directory directory = FSDirectory.open(new File("/path/to/index")); // disk index storage
Если вы хотите добавить, обновить или удалить документ, вам нужен IndexWriter:
IndexWriter writer = new IndexWriter(directory, analyzer, true, new IndexWriter.MaxFieldLength(25000));
Любой документ (текстовый файл в вашем случае) представляет собой набор полей. Чтобы создать документ, который будет содержать информацию о вашем файле, используйте это:
Document doc = new Document();
String title = nameOfYourFile;
doc.add(new Field("title", title, Field.Store.YES, Field.Index.ANALYZED)); // adding title field
String content = contentsOfYourFile;
doc.add(new Field("content", content, Field.Store.YES, Field.Index.ANALYZED)); // adding content field
writer.addDocument(doc); // writing new document to the index
Field
конструктор принимает имя поля, его текст и как минимум 2 дополнительных параметра. Сначала флаг, который показывает, должен ли Lucene хранить это поле. Если оно равно Field.Store.YES
, у вас будет возможность получить весь текст обратно из индекса, в противном случае будет храниться только информация об этом из индекса.
Второй параметр показывает, должен ли Lucene индексировать это поле или нет. Используйте Field.Index.ANALYZED
для любого поля, в котором вы собираетесь искать.
Обычно вы используете оба параметра, как показано выше.
Не забудьте закрыть IndexWriter
после выполнения задания:
writer.close();
Поиск немного сложен. Вам понадобится несколько классов: Query
и QueryParser
, чтобы сделать запрос Lucene из строки, IndexSearcher
для фактического поиска, TopScoreDocCollector
для сохранения результатов (он передается IndexSearcher
в качестве параметра) и ScoreDoc
перебирать результаты. Следующий фрагмент показывает, как все это состоит:
IndexSearcher searcher = new IndexSearcher(directory);
QueryParser parser = new QueryParser(Version.LUCENE_30, "content", analyzer);
Query query = parser.parse("terms to search");
TopScoreDocCollector collector = TopScoreDocCollector.create(HOW_MANY_RESULTS_TO_COLLECT, true);
searcher.search(query, collector);
ScoreDoc[] hits = collector.topDocs().scoreDocs;
// `i` is just a number of document in Lucene. Note, that this number may change after document deletion
for (int i = 0; i < hits.length; i++) {
Document hitDoc = searcher.doc(hits[i].doc); // getting actual document
System.out.println("Title: " + hitDoc.get("title"));
System.out.println("Content: " + hitDoc.get("content"));
System.out.println();
}
Записать второй аргумент в конструктор QueryParser
- это поле по умолчанию, то есть поле, в котором будет производиться поиск, если не указан квалификатор. Например, если ваш запрос «title: term», Lucene будет искать слово «term» в поле «title» всех документов, но если ваш запрос просто «term», если будет искать в поле по умолчанию, в этом случае - «содержание». Для получения дополнительной информации см. Синтаксис запроса Lucene .
QueryParser
также принимает анализатор в качестве последнего аргумента. Это должен быть тот же анализатор, который вы использовали для индексирования текста.
Последнее, что вы должны знать, это TopScoreDocCollector.create
первый параметр. Это просто число, которое представляет, сколько результатов вы хотите собрать. Например, если оно равно 100, Lucene соберет только первые (по количеству баллов) 100 результатов и отбросит остальные. Это всего лишь процесс оптимизации - вы собираете лучшие результаты, и если вы не удовлетворены им, вы повторяете поиск с большим числом.
Наконец, не забудьте закрыть поисковик и каталог, чтобы не потерять системные ресурсы:
searcher.close();
directory.close();
РЕДАКТИРОВАТЬ: Также см. Демо-класс IndexFiles из Исходники Lucene 3.0 .