コード例 #1
0
        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);
        }
コード例 #2
0
        /// <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();
        }
コード例 #3
0
        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();
        }