使用Lucene.net进行分页

我正在开发一个使用Asp.net 3.5和Lucene.Net的.Net应用程序我在一个asp.net数据网格中显示Lucene.Net给出的搜索结果。 我需要为这个aspx页面实现Paging(每页10条记录)。

如何使用Lucene.Net完成此操作?

这是一种使用Lucene.Net构建与特定页面匹配的简单列表的方法。 这不是ASP.Net特有的。

int first = 0, last = 9; // TODO: Set first and last to correct values according to page number and size Searcher searcher = new IndexSearcher(YourIndexFolder); Query query = BuildQuery(); // TODO: Implement BuildQuery Hits hits = searcher.Search(query); List results = new List(); for (int i = first; i <= last && i < hits.Length(); i++) results.Add(hits.Doc(i)); // results now contains a page of documents matching the query 

基本上Hits集合非常轻量级。 获取此列表的成本很低。 您只需通过调用hits.Doc(i)来构建页面来实例化所需的文档。

我所做的是遍历命中并将它们插入到db中的临时表中。 然后我可以运行一个常规的SQL查询 – 将临时表与其他表连接起来 – 并为网格提供它想要的DataSet / DataView。

请注意,我在ONE TRIP中执行插入和查询到db,因为我只使用一个SQL批处理。

 void Page_Load(Object sender, EventArgs e) { dbutil = new DbUtil(); security = new Security(); security.check_security(dbutil, HttpContext.Current, Security.ANY_USER_OK); Lucene.Net.Search.Query query = null; try { if (string.IsNullOrEmpty(Request["query"])) { throw new Exception("You forgot to enter something to search for..."); } query = MyLucene.parser.Parse(Request["query"]); } catch (Exception e3) { display_exception(e3); } Lucene.Net.Highlight.QueryScorer scorer = new Lucene.Net.Highlight.QueryScorer(query); Lucene.Net.Highlight.Highlighter highlighter = new Lucene.Net.Highlight.Highlighter(MyLucene.formatter, scorer); highlighter.SetTextFragmenter(MyLucene.fragmenter); // new Lucene.Net.Highlight.SimpleFragmenter(400)); StringBuilder sb = new StringBuilder(); string guid = Guid.NewGuid().ToString().Replace("-", ""); Dictionary dict_already_seen_ids = new Dictionary(); sb.Append(@" create table #$GUID ( temp_bg_id int, temp_bp_id int, temp_score float, temp_text nvarchar(3000) ) "); lock (MyLucene.my_lock) { Lucene.Net.Search.Hits hits = null; try { hits = MyLucene.search(query); } catch (Exception e2) { display_exception(e2); } // insert the search results into a temp table which we will join with what's in the database for (int i = 0; i < hits.Length(); i++) { if (dict_already_seen_ids.Count < 100) { Lucene.Net.Documents.Document doc = hits.Doc(i); string bg_id = doc.Get("bg_id"); if (!dict_already_seen_ids.ContainsKey(bg_id)) { dict_already_seen_ids[bg_id] = 1; sb.Append("insert into #"); sb.Append(guid); sb.Append(" values("); sb.Append(bg_id); sb.Append(","); sb.Append(doc.Get("bp_id")); sb.Append(","); //sb.Append(Convert.ToString((hits.Score(i)))); sb.Append(Convert.ToString((hits.Score(i))).Replace(",", ".")); // Somebody said this fixes a bug. Localization issue? sb.Append(",N'"); string raw_text = Server.HtmlEncode(doc.Get("raw_text")); Lucene.Net.Analysis.TokenStream stream = MyLucene.anal.TokenStream("", new System.IO.StringReader(raw_text)); string highlighted_text = highlighter.GetBestFragments(stream, raw_text, 1, "...").Replace("'", "''"); if (highlighted_text == "") // someties the highlighter fails to emit text... { highlighted_text = raw_text.Replace("'","''"); } if (highlighted_text.Length > 3000) { highlighted_text = highlighted_text.Substring(0,3000); } sb.Append(highlighted_text); sb.Append("'"); sb.Append(")\n"); } } else { break; } } //searcher.Close(); }