Главная > Lucene > Знакомимся с Lucene.NET

Знакомимся с Lucene.NET

Введение



О Lucene я слышал уже давно, но попробовать данную библиотеку как-то не удавалось. На этой неделе я всё-таки решил поисследовать ее. Начал с простых примеров, а дальше, возможно, заиспользую Lucene в проекте на работе. Чтобы самому более подробно разобраться с данной библиотекой, решил написать о ней несколько статей. В данной статье хочу рассказать про основы работы с Lucene, а именно: про построение индекса и про поиск документов.


Что такое Lucene?



The Apache Lucene — это свободная библиотека для высокоскоростного полнотекстового поиска, написанная на Java. Lucene портированна на многие популярные языки программирования, в том числе и на .NET.
Основные особенности данной библиотеки:

  • высокоскоростная индексация;
  • мощный, точный и эффективный поисковый алгоритм.

Если вам необходимо встроить возможности Full-Text Search’а в ваше .NET-приложение, то Lucene.NET отличный кандидат. При помощи Lucene можно построить такую систему поиска, которая будет удовлетворять любым вашим требованиям. Lucene может использоваться для индексирования практически любого типа контента. Важно понимать, что созданный данные, по которым строится индекс могут меняться, поэтому необходимо постоянно обновлять используемый индекс.

Что нужно для работы с Lucene.NET?



Все исходники Lucene.NET открыты и находятся в SVN-репозитории. Соответственно их можно скачать, собрать и использовать полученную dll. Уже собранную библиотеку на официальном сайте скачать не получится, но можно ее взять из любого Open Source проекта, использующего Lucene.NET, например, Subtext (но там может оказаться не последняя версия).

UPDATE: На момент написания статьи выложенных бинарников не было, но теперь их выложили здесь. И обновился сам сайт проекта.


Построение индекса



После добавления Lucene.NET в референсы вашего проекта, необходимо создать индекс. Обычно он хранится в файлах, но для увеличения производительности его можно записывать в память.
Следующий код добавляет в индекс 1000000 документов:

  1. Analyzer analyzer = new StandardAnalyzer();
  2. IndexWriter writer = new IndexWriter("tmp", analyzer);
  3. for (int i = 0; i < 1000000; i++)
  4. {
  5.   Document doc = new Document();
  6.   doc.Add(
  7.     new Field(
  8.       "id",
  9.       i.ToString(),
  10.       Field.Store.YES,
  11.       Field.Index.NO));
  12.   doc.Add(
  13.     new Field(
  14.       "text",
  15.       string.Format("{0} string.", i),
  16.       Field.Store.YES,
  17.       Field.Index.TOKENIZED));
  18.   writer.AddDocument(doc);
  19.   if (i % 100000 == 0)
  20.      Console.WriteLine(
  21.       "[{1}]: {0} documents are saved.",
  22.       i,
  23.       DateTime.Now);
  24. }
  25. writer.Optimize();
  26. writer.Close();

* This source code was highlighted with Source Code Highlighter.

Первые 2 строки создают Writer, который и будет производить запись в индекс в папку tmp.

В цикле создается документ и в него добавляются несколько полей. Для каждого из полей можно настроить будет оно сохраняться/индексироваться или нет. Таким образом, в данном примере по полю text создается индекс, а по id — нет и оба поля хранятся в индексе.

Вызов метода Optimize уменьшит объем созданных файлов, но он может занять некоторое время, и это надо учитывать при построении высоконагруженных систем.

На моем ноутбуке 100000 таких документов сохраняется за 1-2 секунды, что мне кажется хорошей производительностью, хотя есть идеи в будущем поплотней потестировать производительность Lucene.NET.


Построение запросов



Для того, чтобы найти документы, достаточно написать следующий код:

  1. Analyzer analyzer = new StandardAnalyzer();
  2.  
  3. QueryParser parser = new QueryParser("text", analyzer);
  4. Query query = parser.Parse("string");
  5.  
  6. IndexSearcher searcher = new IndexSearcher("tmp");
  7. Hits hits = searcher.Search(query);
  8.  
  9. int results = hits.Length();
  10. Console.WriteLine("Found {0} results", results);
  11. for (int i = 0; i < results; i++)
  12. {
  13.   Document doc = hits.Doc(i);
  14.   Console.WriteLine("ID: {0}", doc.Get("id"));
  15.   Console.WriteLine("Text found: {0}", doc.Get("text"));
  16. }
  17.  
  18. searcher.Close();

* This source code was highlighted with Source Code Highlighter.

Т.е. мы создаем запрос, выполняем поиск и проходимся по всем документам удовлетворяющим запросу.

Запрос можно создать несколько иначе:

Query query = new TermQuery(new Term("text", "string"));


Что дальше?



Все вышеописанное — это простейший пример создания индекса и поиска по нему. В следующей статье я постараюсь описать основные элементы, которые используются в Lucene.NET.
 

Ссылки


  1. Getting started with Lucene.NET
  2. Lucene.NET Your first application
  3. How to get started with Lucene.NET
  4. Lucene tutorial


Связанные статьи


  1. Язык запросов Lucene.NET
  2. Анализаторы в Lucene.NET


Progg it

Рубрики:Lucene Метки: , , ,
  1. atott
    4 августа, 2011 в 5:15 пп

    А есть ли какие то специализированные анализаторы для русского языка, которые могли бы учесть русскую морфологию и т.п.?

    • 4 августа, 2011 в 5:20 пп

      В оригинальном Lucene (на Java) есть RussianAnalyzer, но к сожалению в .NET версии его нет. На GotDotNet заходил вопрос про анализатор на русском языке (http://www.gotdotnet.ru/forums/4/103749/), возможно это поможет.

  2. 6 августа, 2011 в 11:45 дп

    Привет, отчасти помогло. Поднять в воздух стеммер для русского языка мне не удалось, даже примерчик который поставляется вместе с проектом не работает, не говоря уже о самой индексации и т.п. Дебажить лень, а собрать собственный анализатор оказалось очень просто. Может быть кому-то пригодится http://atott.ru/note/view/1

  1. 20 марта, 2011 в 4:03 пп

Оставьте комментарий