3 // SearchableIndex.cs: Index that uses Lucene to search through the docs
5 // Author: Mario Sopena
10 using System.Collections.Generic;
12 using Lucene.Net.Index;
13 using Lucene.Net.Documents;
14 using Lucene.Net.Analysis;
15 using Lucene.Net.Analysis.Standard;
16 using Lucene.Net.Search;
17 using Lucene.Net.QueryParsers;
18 using Lucene.Net.Store;
22 public class SearchableIndex
24 const int maxSearchCount = 30;
26 IndexSearcher searcher;
38 public static SearchableIndex Load (string dir)
40 SearchableIndex s = new SearchableIndex ();
43 //s.searcher = new IndexSearcher (dir);
44 // TODO: parametrize that depending if we run on the desktop (low footprint) or the server (use RAMDirectory for instance)
45 s.searcher = new IndexSearcher (FSDirectory.Open (dir));
46 } catch (IOException) {
47 Console.WriteLine ("Index nonexistent or in bad format");
53 public Result Search (string term)
55 return Search (term, maxSearchCount);
58 public Result Search (string term, int count)
60 return Search (term, count, 0);
63 public Result Search (string term, int count, int start) {
65 term = term.ToLower ();
66 Term htTerm = new Term ("hottext", term);
67 Query qq1 = new FuzzyQuery (htTerm);
68 Query qq2 = new TermQuery (htTerm);
70 Query qq3 = new PrefixQuery (htTerm);
72 DisjunctionMaxQuery q1 = new DisjunctionMaxQuery (0f);
76 Query q2 = new TermQuery (new Term ("text", term));
78 Query q3 = new TermQuery (new Term ("examples", term));
80 DisjunctionMaxQuery q = new DisjunctionMaxQuery (0f);
86 TopDocs top = SearchInternal (q, count, start);
87 Result r = new Result (term, searcher, top.ScoreDocs);
89 } catch (IOException) {
90 Console.WriteLine ("No index in {0}", dir);
95 TopDocs SearchInternal (Query q, int count, int start)
97 // Easy path that doesn't involve creating a Collector ourselves
98 // watch for Lucene.NET improvement on that (like searcher.SearchAfter)
100 return searcher.Search (q, count);
102 var weight = searcher.CreateWeight (q); // TODO: reuse weight instead of query
103 var collector = TopScoreDocCollector.Create (start + count + 1, false);
104 searcher.Search (q, collector);
106 return collector.TopDocs (start, count);
109 public Result FastSearch (string term, int number)
112 term = term.ToLower ();
113 Query q1 = new TermQuery (new Term ("hottext", term));
114 Query q2 = new PrefixQuery (new Term ("hottext", term));
116 DisjunctionMaxQuery q = new DisjunctionMaxQuery (0f);
119 TopDocs top = searcher.Search (q, number);
120 return new Result (term, searcher, top.ScoreDocs);
121 } catch (IOException) {
122 Console.WriteLine ("No index in {0}", dir);
129 // An object representing the search term with the results
131 public class Result {
141 get { return docs.Length; }
144 public Document this [int i] {
145 get { return searcher.Doc (docs[i].Doc); }
148 public string GetTitle (int i)
150 Document d = this[i];
151 return d == null ? string.Empty : d.Get ("title");
154 public string GetUrl (int i)
156 Document d = this[i];
157 return d == null ? string.Empty : d.Get ("url");
160 public string GetFullTitle (int i)
162 Document d = this[i];
163 return d == null ? string.Empty : d.Get ("fulltitle");
166 public float Score (int i)
168 return docs[i].Score;
171 public Result (string Term, Searcher searcher, ScoreDoc[] docs)
174 this.searcher = searcher;