Lucene.Net API Search Demo
Downloads
- LuceneNetTutorial-1.1.zip 9973 kB
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>