Lucene.NET tutorials and examples

Lucene.Net API Search Demo

This sample project (C#, Visual Studio 2010) indexes and searches Lucene.Net API documentation (5644 HTML files). Includes C# source code.

Downloads

Features

This sample project (C#, Visual Studio 2010) indexes and searches Lucene.Net API documentation (5644 HTML files).

  • Indexed file size (total): 15 MB
  • Index size: 8 MB (stores the extracted text)
  • Average search time: 0,004 sec

Online Demo

You can test this ASP.NET application online:

Indexing

The Indexer is a simple console application that finds all HTML file in a given directory and adds them to the index.

The index is recreated when you run the Indexer.

This is the indexer core:

IndexWriter writer = new IndexWriter(FSDirectory.Open(directory), new StandardAnalyzer(Version.LUCENE_30), true, IndexWriter.MaxFieldLength.LIMITED);

Document doc = new Document();

string text = "this is the text that is going to be indexed";
string path = "c:/lucene.net/app/text.txt";
string title = "text";

doc.Add(new Field("text", text, Field.Store.YES, Field.Index.ANALYZED));
doc.Add(new Field("path", path, Field.Store.YES, Field.Index.NOT_ANALYZED));
doc.Add(new Field("title", title, Field.Store.YES, Field.Index.ANALYZED));

writer.AddDocument(doc);

writer.Optimize();
writer.Dispose();

Searching

Searcher is a sample ASP.NET application (C#) that uses the index generated by the Indexer to search our files.

The following code opens the index, searches it using a query supplied in q URL parameter and stores the result in results DataTable.

// create the searcher
// index is placed in "index" subdirectory
string indexDirectory = Server.MapPath("~/App_Data/index");

var analyzer = new StandardAnalyzer(Version.LUCENE_30);

IndexSearcher searcher = new IndexSearcher(FSDirectory.Open(indexDirectory)); 

// parse the query, "text" is the default field to search
var parser = new QueryParser(Version.LUCENE_30, "text", analyzer);

var q = Request.QueryString["q"];
Query query = parser.Parse(q); 

// create the result DataTable
var result = new DataTable();

results.Columns.Add("title", typeof(string));
results.Columns.Add("sample", typeof(string));
results.Columns.Add("path", typeof(string));

// search
TopDocs hits = searcher.Search(query, 200);

// showing first 10 results
for (int i = 0; i < 10; i++) 
{
	// get the document from index
	Document doc = searcher.Doc(hits.ScoreDocs[i].Doc);

	// create a new row with the result data
	DataRow row = results.NewRow();
	row["title"] = doc.Get("title");
	row["path"] = doc.Get("path");

	results.Rows.Add(row);
} 
searcher.Dispose();

Now we will will add a sample fragment of the text that is relevant to the query and highlight the query in the sample.

This can be done using Highlighter class from Lucene.Net.Contrib.Highlighter.dll library.

// create the searcher
// index is placed in "index" subdirectory
string indexDirectory = Server.MapPath("~/App_Data/index");

var analyzer = new StandardAnalyzer(Version.LUCENE_30);

IndexSearcher searcher = new IndexSearcher(FSDirectory.Open(indexDirectory)); 

// parse the query, "text" is the default field to search
var parser = new QueryParser(Version.LUCENE_30, "text", analyzer);

var q = Request.QueryString["q"];
Query query = parser.Parse(q); 

// create the result DataTable
var result = new DataTable();

results.Columns.Add("title", typeof(string));
results.Columns.Add("sample", typeof(string));
results.Columns.Add("path", typeof(string));

// search
TopDocs hits = searcher.Search(query, 200);

// create highlighter
IFormatter formatter = new SimpleHTMLFormatter("<span style=\"font-weight:bold;\">", "</span>");
SimpleFragmenter fragmenter = new SimpleFragmenter(80);
QueryScorer scorer = new QueryScorer(query);
Highlighter highlighter = new Highlighter(formatter, scorer);
highlighter.TextFragmenter = fragmenter;

// showing first 10 results
for (int i = 0; i < 10; i++) 
{
	// get the document from index
	Document doc = searcher.Doc(hits.ScoreDocs[i].Doc);

	TokenStream stream = analyzer.TokenStream("", new StringReader(doc.Get("text")));
	String sample= highlighter.GetBestFragments(stream, doc.Get("text"), 2, "...");

	// create a new row with the result data
	DataRow row = results.NewRow();
	row["title"] = doc.Get("title");
	row["path"] = doc.Get("path");
	row["sample"] = sample;

	results.Rows.Add(row);
} 
searcher.Dispose();

The results DataTable is displayed using a simple Repeater control.

<asp:repeater id="Repeater1" runat="server" DataSource="<%# Results %>">
  <ItemTemplate>
    <p>
      <a href='<%# DataBinder.Eval(Container.DataItem, "path")  %>' class="link"><%# DataBinder.Eval(Container.DataItem, "title")  %></a>
	  <br/>
      <span class="sample">
        <%# DataBinder.Eval(Container.DataItem, "sample")  %>
      </span>
    </p>
  </ItemTemplate>
</asp:repeater>