首先,关于Lucene.Net 的文章已经很多了。我这次决定写出来只是为了练练手,虽然在别人看来没什么用,但是自己确实是手动实践了一把。我个人觉得还是有意义的。爱折腾、敢于实践、才能有所收获,才能发现问题。不要怕自己写的东西有问题,有问题才更好呢,可以让更多的人看见,提意见的当然是好,鄙视的……我也接受,给自己 动力去思考。

想让自己时刻保持着这种程序员-->代码心态、人都是带有惰性的,一旦玩起来 呵呵...

效果显示

瞎折腾之 Lucene.Net + MVC 搜索功能(上)

瞎折腾之 Lucene.Net + MVC 搜索功能(上)

进入主题

相信大家对于LuceneNet 并不陌生了,园子里面的文章很多。

参考文章:

http://www.cnblogs.com/birdshover/category/152283.html

http://www.cnblogs.com/psforever/archive/2011/10/06/2200019.html

 

界面是一个在线工具自己手动构的,可以随意的设计自己想要的界面。但是引用的css居然不是Bootstrap的css,这点得注意。

css样式引用地址:http://www.bootcss.com/p/layoutit/css/bootstrap-combined.min.css

            http://www.bootcss.com/p/layoutit/css/layoutit.css

在线工具地址:http://www.bootcss.com/p/layoutit/

 

数据库大概8w条记录,每次最多取出1W条查询结果。正常人也不会看完这么多的。

 核心代码

方法

        /// <summary>
        /// 获得搜索列表
        /// </summary>
        /// <param name="keyword">关键字</param>
        /// <param name="pageSize"></param>
        /// <param name="currentPage">当前页码</param>
        /// <param name="count"></param>
        /// <param name="pageCount"></param>
        /// <param name="isLike">是否开启模糊查询</param>
        /// <returns></returns>
        public static List<StoreInfo> GetSearchList(string keyword, int pageSize, int currentPage, out int count, out int pageCount, bool isLike = false)
        {
            string keywords = keyword; //获取用户输入关键字,以备设置高亮显示
            string strIndexPath = INDEX_STORE_PATH;
            List<StoreInfo> storeList = new List<StoreInfo>();
            StoreInfo modelstore;
            pageCount = 0;
            count = 0;

            IndexSearcher search = null;
            try
            {
                search = new IndexSearcher(FSDirectory.Open(new System.IO.DirectoryInfo(strIndexPath)), true);
            }
            catch (Exception)
            {
                return null;
            }

            keyword = GetKeyWordsSplitBySpace(keyword, new PanGuTokenizer());

            QueryParser titleQueryParser = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, "body", new PanGuAnalyzer(true));
            Query titleQuery = titleQueryParser.Parse(keyword);

            Query PrefixQuery_title = null;
            Query PrefixQuery_body = null;
            Query FuzzyQuery_Title = null;
            Query FuzzyQuery_body = null;
            Query WildcardQuery_title = null;
            Query WildcardQuery_body = null;

            if (isLike)
            {
                //以什么开头,输入“ja”就可以搜到包含java和javascript两项结果了
                PrefixQuery_title = new PrefixQuery(new Term("title", keywords));
                PrefixQuery_body = new PrefixQuery(new Term("body", keywords));
                //直接模糊匹配,假设你想搜索跟‘wuzza’相似的词语,你可能得到‘fuzzy’和‘wuzzy’。
                FuzzyQuery_Title = new FuzzyQuery(new Term("title", keywords));
                FuzzyQuery_body = new FuzzyQuery(new Term("body", keywords));
                //通配符搜索
                WildcardQuery_title = new WildcardQuery(new Term("title", keywords));
                WildcardQuery_body = new WildcardQuery(new Term("body", keywords));
            }

            //MultiFieldQueryParser
            BooleanQuery bq = new BooleanQuery();

            bq.Add(titleQuery, BooleanClause.Occur.SHOULD);//表示条件关系为“or”,BooleanClause.Occur.MUST表示“and”,BooleanClause.Occur.MUST_NOT表示“not”
   
            if (isLike)
            {
                bq.Add(PrefixQuery_title, BooleanClause.Occur.SHOULD);
                bq.Add(PrefixQuery_body, BooleanClause.Occur.SHOULD);
                bq.Add(FuzzyQuery_Title, BooleanClause.Occur.SHOULD);
                bq.Add(FuzzyQuery_body, BooleanClause.Occur.SHOULD);
                bq.Add(WildcardQuery_title, BooleanClause.Occur.SHOULD);
                bq.Add(WildcardQuery_body, BooleanClause.Occur.SHOULD);
            }

            //创建一个结果收集器(收集结果最大数为1000页)
            TopScoreDocCollector collector = TopScoreDocCollector.create(pageSize * 1000, true);
            search.Search(bq, null, collector);
            TopDocs topDoc = collector.TopDocs(0, collector.GetTotalHits());

            //搜索结果总数超出指定收集器大小,则摈弃
            if (topDoc.totalHits > pageSize * 1000)
                count = pageSize * 1000;
            else
                count = topDoc.totalHits;

            int i = (currentPage - 1) * pageSize;

            #region
            Lucene.Net.Documents.Document docs;
            PanGu.HighLight.Highlighter highlighter;
            PanGu.HighLight.SimpleHTMLFormatter simpleHTMLFormatter;

            while (i < count && storeList.Count < pageSize)
            {
                modelstore = new StoreInfo();

                docs = search.Doc(topDoc.scoreDocs[i].doc);
                try
                {
                    string strTitle = docs.Get("title");
                    string strContent = docs.Get("body");
                    modelstore.Store_ID = Convert.ToInt32(docs.Get("id"));

                    //高亮显示设置
                    simpleHTMLFormatter = new PanGu.HighLight.SimpleHTMLFormatter("<span style=\"color:red;\">", "</span>");
                    highlighter = new PanGu.HighLight.Highlighter(simpleHTMLFormatter, new PanGu.Segment());
                    highlighter.FragmentSize = 200;

                    //string GetBestFragment(keywords,content)方法会按照SimpleHTMLFormatter构造的格式对content中关键字进行高亮显示
                    //但如果content中不包含keywords则会返回空值,故需要按照如下进行判断
                    modelstore.Description = highlighter.GetBestFragment(keywords, strContent);
                    if (string.IsNullOrEmpty(modelstore.Description))
                    {
                        modelstore.Description = strContent;
                    }
                    modelstore.Store_Name = highlighter.GetBestFragment(keywords, strTitle);
                    if (string.IsNullOrEmpty(modelstore.Store_Name))
                    {
                        modelstore.Store_Name = strTitle;
                    }
                }
                catch (Exception e)
                {
                    continue;
                }
                finally
                {
                    storeList.Add(modelstore);
                    i++;
                }
            }
            #endregion

            search.Close();
            pageCount = Convert.ToInt32(Math.Ceiling((double)collector.GetTotalHits() / pageSize));

            return storeList;
        }
View Code

相关文章: