Lucene Index created can be searched using "IndexSearcher" class in Lucene.Net.Search Namespace.
"IndexSearcher" requires following input for searching lucene index
Lucene.Net.Search.Query - Lucene class helps to build a lucene query on given fields with respective clause
various clauses can be build using Lucene.Net.Search.BooleanClause class.
Lucene.Net.Search.TopDocCollector - helps in creating collector with filter options for required search
Lucene.Net.Search.TopFieldDocCollector - also helps in creating collector with required filter and sort options
Lucene.Net.Search.ScoreDoc gets the resultant hits from collector.TopDocs().scoreDocs
The resultant hits can be looped to get the matched lucene documents.
The following "GetSearchResult" function helps in searching the Lucene Index with above mentioned Lucene classes.
The result of the "GetSearchResult" function would be XmlDocument with result as "SEARCHRESULT" nodes.
public static XmlDocument GetSearchResult(string Indexpath, string[] querys, string[] fields
, BooleanClause.Occur[] clauses, string[] sortingfields)
{
//XMLDocument is created to return output records
XmlDocument xResDoc = new XmlDocument();
xResDoc.LoadXml("<SEARCHRESULTS></SEARCHRESULTS>");
try
{
// This block will parse the given queries
// (i.e) would remove characters other than a-z and 0-9
for (int i = 0; i < querys.Length; i++)
{
querys[i] = querys[i].ToLower();
querys[i] = System.Text.RegularExpressions.Regex.Replace(querys[i]
, "[^a-z0-9]", " ");
while (querys[i].Contains(" "))
querys[i] = querys[i].Replace(" ", " ");
}
//
if (System.IO.Directory.Exists(Indexpath))
{
// Open's Already created Lucene Index for searching
Lucene.Net.Index.IndexReader idxReader = Lucene.Net.Index.IndexReader.Open(Indexpath);
Searcher searcher = new IndexSearcher(idxReader);
//Creates a Lucene Query with given search inputs
Query qry = MultiFieldQueryParser.Parse(querys, fields, clauses
, new StandardAnalyzer());
ScoreDoc[] hits;
//Assigns No. of Records to be fetched
//here idxReader max records is used
//can be changed to get specific top records
int top = idxReader.MaxDoc();
//To get output with specific sort
if (sortingfields.Length > 0)
{
TopFieldDocCollector collector = new TopFieldDocCollector(idxReader
, new Sort(sortingfields), top);
searcher.Search(qry, collector);
hits = collector.TopDocs().scoreDocs;
}
else //To get output without specific sort
{
TopDocCollector collector = new TopDocCollector(top);
searcher.Search(qry, collector);
hits = collector.TopDocs().scoreDocs;
}
//Loops through the output records and creates an XMLElement for XML Output
for (int i = 0; i < hits.Length; i++)
{
int docId = hits[i].doc;
Document doc = searcher.Doc(docId);
XmlElement xEle = xResDoc.CreateElement("SEARCHRESULT");
foreach (Field fl in doc.Fields())
{
xEle.SetAttribute(fl.Name(), doc.Get(fl.Name()));
}
xResDoc.DocumentElement.AppendChild(xEle);
}
searcher.Close();
idxReader.Close();
}
}
catch (Exception ex)
{
//Print Error Message
}
return xResDoc;
}
The above function can be used as
string[] querys = { "dominos pizza" };
string[] fields = { "title"};
Lucene.Net.Search.BooleanClause.Occur[] clauses = { Lucene.Net.Search.BooleanClause.Occur.MUST };
string[] sortby = { "id"};
XmlDocument xDoc = GetSearchResult(@"C:\luceneindexpath\", querys, fields, clauses, sortby);
where,
querys is string array of user search terms.
fields is string array of fields in Lucene Index on with searching to be done.
clauses is Lucene.Net.Search.BooleanClause.Occur array of BooleanClause to be applied on different search term.
sortby is string array of fields on which sorting to be performed.
Length of all input array should match
I am using this as is - after having created an index inprevious tutorial- trying to bind it to a ds - no luck? No results - how can I tell where I am going wrong? DataSet myDs = new DataSet(); myDs.ReadXml(new XmlNodeReader(xDoc)); if (myDs.Tables.Count > 0) { this.GridView1.DataSource = myDs; this.GridView1.DataBind(); } else { Response.Write("Empty"); }
i think it will be much easier just to enumerate xml rows Greate post anyway!