public object Search(string keyWord, int pageIndex, int pageSize) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); string indexPath = Directory.GetCurrentDirectory() + "/Index"; FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NoLockFactory()); IndexReader reader = IndexReader.Open(directory, true); //创建IndexSearcher准备进行搜索。 IndexSearcher searcher = new IndexSearcher(reader); // 查询条件 keyWord = GetKeyWordsSplitBySpace(keyWord, new PanGuTokenizer()); //创建QueryParser查询解析器。用来对查询语句进行语法分析。 //QueryParser调用parser进行语法分析,形成查询语法树,放到Query中。 QueryParser msgQueryParser = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, "Content", new PanGuAnalyzer(true)); Query msgQuery = msgQueryParser.Parse(keyWord); //TopScoreDocCollector:盛放查询结果的容器 //numHits 获取条数 TopScoreDocCollector collector = TopScoreDocCollector.create(1000, true); //IndexSearcher调用search对查询语法树Query进行搜索,得到结果TopScoreDocCollector。 // 使用query这个查询条件进行搜索,搜索结果放入collector searcher.Search(msgQuery, null, collector); // 从查询结果中取出第n条到第m条的数据 ScoreDoc[] docs = collector.TopDocs(0, 1000).scoreDocs; stopwatch.Stop(); // 遍历查询结果 List <ReturnModel> resultList = new List <ReturnModel>(); var pm = new Page <ReturnModel> { PageIndex = pageIndex, PageSize = pageSize, TotalRows = docs.Length }; pm.TotalPages = pm.TotalRows / pageSize; if (pm.TotalRows % pageSize != 0) { pm.TotalPages++; } for (int i = (pageIndex - 1) * pageSize; i < pageIndex * pageSize && i < docs.Length; i++) { var doc = searcher.Doc(docs[i].doc); var content = HighlightHelper.HighLight(keyWord, doc.Get("Content")); var result = new ReturnModel { Title = doc.Get("Title"), Content = content, Count = Regex.Matches(content, "<font").Count }; resultList.Add(result); } pm.LsList = resultList; var elapsedTime = stopwatch.ElapsedMilliseconds + "ms"; var list = new { list = pm, ms = elapsedTime }; return(list); }
/// <summary> /// 获取搜索结果 /// </summary> protected void btnGetSearchResult_Click(object sender, EventArgs e) { string keyword = txtKeyWords.Text; string indexPath = Context.Server.MapPath("~/Index"); // 索引文档保存位置 FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NoLockFactory()); IndexReader reader = IndexReader.Open(directory, true); IndexSearcher searcher = new IndexSearcher(reader); // 查询条件 PhraseQuery query = new PhraseQuery(); // 等同于 where contains("msg",kw) query.Add(new Term("msg", keyword)); // 两个词的距离大于100(经验值)就不放入搜索结果,因为距离太远相关度就不高了 query.SetSlop(100); // TopScoreDocCollector:盛放查询结果的容器 TopScoreDocCollector collector = TopScoreDocCollector.create(1000, true); // 使用query这个查询条件进行搜索,搜索结果放入collector searcher.Search(query, null, collector); // 从查询结果中取出第m条到第n条的数据 // collector.GetTotalHits()表示总的结果条数 ScoreDoc[] docs = collector.TopDocs(0, collector.GetTotalHits()).scoreDocs; // 遍历查询结果 IList <SearchResult> resultList = new List <SearchResult>(); for (int i = 0; i < docs.Length; i++) { // 拿到文档的id,因为Document可能非常占内存(DataSet和DataReader的区别) int docId = docs[i].doc; // 所以查询结果中只有id,具体内容需要二次查询 // 根据id查询内容:放进去的是Document,查出来的还是Document Document doc = searcher.Doc(docId); SearchResult result = new SearchResult(); result.Id = Convert.ToInt32(doc.Get("id")); result.Msg = HighlightHelper.HighLight(keyword, doc.Get("msg")); resultList.Add(result); } // 绑定到Repeater rptSearchResult.DataSource = resultList; rptSearchResult.DataBind(); }
private void BindSearchResult(string keyword, int startIndex, int pageSize, out int totalCount) { string indexPath = Context.Server.MapPath("~/Index"); // 索引文档保存位置 FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NoLockFactory()); IndexReader reader = IndexReader.Open(directory, true); IndexSearcher searcher = new IndexSearcher(reader); #region v1.0 单条件查询 //// 查询条件 //PhraseQuery query = new PhraseQuery(); //// 分词后加入查询 //IEnumerable<string> keyList = SplitHelper.SplitWords(keyword); //foreach (var key in keyList) //{ // query.Add(new Term("msg", key)); //} //// 两个词的距离大于100(经验值)就不放入搜索结果,因为距离太远相关度就不高了 //query.SetSlop(100); #endregion #region v2.0 多条件查询 IEnumerable <string> keyList = SplitHelper.SplitWords(keyword); PhraseQuery queryTitle = new PhraseQuery(); foreach (var key in keyList) { queryTitle.Add(new Term("title", key)); } queryTitle.SetSlop(100); PhraseQuery queryMsg = new PhraseQuery(); foreach (var key in keyList) { queryMsg.Add(new Term("msg", key)); } queryMsg.SetSlop(100); BooleanQuery query = new BooleanQuery(); query.Add(queryTitle, BooleanClause.Occur.SHOULD); // SHOULD => 可以有,但不是必须的 query.Add(queryTitle, BooleanClause.Occur.SHOULD); // SHOULD => 可以有,但不是必须的 #endregion // TopScoreDocCollector:盛放查询结果的容器 TopScoreDocCollector collector = TopScoreDocCollector.create(1000, true); // 使用query这个查询条件进行搜索,搜索结果放入collector searcher.Search(query, null, collector); // 首先获取总条数 totalCount = collector.GetTotalHits(); // 从查询结果中取出第m条到第n条的数据 ScoreDoc[] docs = collector.TopDocs(startIndex, pageSize).scoreDocs; // 遍历查询结果 IList <SearchResult> resultList = new List <SearchResult>(); for (int i = 0; i < docs.Length; i++) { // 拿到文档的id,因为Document可能非常占内存(DataSet和DataReader的区别) int docId = docs[i].doc; // 所以查询结果中只有id,具体内容需要二次查询 // 根据id查询内容:放进去的是Document,查出来的还是Document Document doc = searcher.Doc(docId); SearchResult result = new SearchResult(); result.Url = "ViewArticle.aspx?id=" + doc.Get("id"); result.Title = HighlightHelper.HighLight(keyword, doc.Get("title")); result.Msg = HighlightHelper.HighLight(keyword, doc.Get("msg")) + "......"; resultList.Add(result); } // 绑定到Repeater rptSearchResult.DataSource = resultList; rptSearchResult.DataBind(); }