Custom Search
Logiclabz
  • Home
  • C#
  • Search Lucene Index in .Net C# with sorting options

Search Lucene Index in .Net C# with sorting options

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



Leave a reply


Do you like this post?