全文检索:分词,索引

1 篇文章 0 订阅
1 篇文章 0 订阅

主要用到lucene索引技术及盘古分词技术,可创建索引,修改索引,删除索引等全套代码。

此代码直接复制调用即可,注意生成索引文件夹(SearchIndex),如果大家有什么不明白的可以直接来问我,715417165  qq

主要业务调用:

using Lucene.api;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Lucene
{
    public partial class lucene : System.Web.UI.Page
    {
        public List<MySearchUnit> searchlist_pangu = null;
        protected void Page_Load(object sender, EventArgs e)
        {
            var action = Request.Params["action"];
            var words = Request.Params["words"];

            switch (action)
            {
                case "createIndex":
                    CreateIndex();
                    break;
                case "deleteAll":
                    DeleteAll();
                    break;
                case "search":
                    Search(words);
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// search
        /// </summary>
        public void Search(string words)
        {
            if (!String.IsNullOrEmpty(words.Trim()))
            {
                #region 全文检索
                int count = 0;
                int pageIndex = 1;
                int pageSize = 2;
                StringBuilder str = new StringBuilder();
                //List<MySearchUnit> searchlist = PanGuLuceneHelper.instance.Search("超级兵王");
                searchlist_pangu = PanGuLuceneHelper.instance.Search("1", Server.HtmlDecode(words), pageIndex, pageSize,false, out count);
                //if (searchlist == null || searchlist.Count == 0)
                //{
                      
                //}
                var versioin = PanGuLuceneHelper.instance.version;
                if (searchlist_pangu == null || searchlist_pangu.Count == 0)
                {
                    str.AppendFormat("检索结果:当前检索无任何值");
                }
                else
                {
                    //PanGuLuceneHelper.instance.version
                }
                #endregion
            }
            else
            {

            }
        }

        /// <summary>
        /// 创建索引
        /// </summary>
        public void CreateIndex()
        {
            //new Random().Next(1, 100000).ToString() 
            List<MySearchUnit> list = new List<MySearchUnit>();
            list.Add(new MySearchUnit("329366", "超级兵王1", "他是雇佣兵世界的王者1,他是令各国元首头疼的兵王!为朋友,他甘愿两肋插刀;为亲人,不惜血溅五步!是龙,终要翱翔于九天之上,携风云之势,一路高歌猛进,混的风生水起。", "1", "", ""));
            list.Add(new MySearchUnit("80000437", "绝世邪神", "重生异世,放荡不羁的叶楚面对众多绝世天才,倾世红颜。他如何踏破苍穹,撼动诸天,世人仰望!", "1", "", ""));
            list.Add(new MySearchUnit("357332", "错入豪门:老公别碰我", "他的残忍,情人的挑衅,最终将她折磨的遍体鳞伤就在要放弃的时候,他却温柔对待。以为他爱上自己的时候,他却挽着别的女人高调结婚,甩给她一张离婚协议书!", "1", "", ""));
            list.Add(new MySearchUnit("358089", "一吻成瘾", "那一夜,她大胆热辣,缠绵过后,本以为两人不会再有交集,却在回国后再次重逢,而他的未婚妻,竟是自己同父异母的姐姐!", "", "", ""));
            list.Add(new MySearchUnit("80000556", "腹黑谋少法医妻", "她是随时可能失业的前任女法医,他是京城贵少,胸有谋略,却黑心无比。她急于把自己嫁出去,摆脱麻烦;他需要娶个女人,给他老子找点麻烦。他掩着眸中的邪恶,“你是自愿和我结婚的吧?”她点头,很认真地和他办了结婚证。她以为,结婚不过是各取所需摆个形式罢了,可他居然……贺鎏阳,你个黑心土匪!", "1", "", ""));
            list.Add(new MySearchUnit("80000789", "无敌萌妻限量版", "他是C城翻手为云覆手为雨的南宫集团首席执行官,身家过亿,却偏偏被当成牛郎睡了,为报此仇,他势要将此人大卸八块拿去喂狗。她是一枚小小设计师,胸怀梦想,无奈现实骨感,可不小心睡了上司之后竟然走了狗屎运成为顶尖设计师!她抱着总裁大腿,感激涕零。为了看牢这个金大腿,她一路过关斩将,弃渣竹马,斗情敌,终于稳固自己总裁夫人的头衔。", "1", "", ""));
            PanGuLuceneHelper.instance.CreateIndex(list,true);//添加索引
        }

        /// <summary>
        /// 删除全部索引
        /// </summary>
        public void DeleteAll()
        {
            PanGuLuceneHelper.instance.DeleteAll();//删除全部
        }

        /// <summary>
        /// 删除key的索引
        /// </summary>
        /// <param name="id"></param>
        public void DeleteID(string id)
        {
            PanGuLuceneHelper.instance.Delete(id);//根据id删除
        }

    }
}


核心处理类:

using Lucene.Net.Analysis;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.QueryParsers;
using Lucene.Net.Search;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;

namespace Lucene.api
{

    /// <summary>
    /// 盘古分词在lucene.net中的使用帮助类
    /// 调用PanGuLuceneHelper.instance
    /// </summary>
    public class PanGuLuceneHelper
    {
        private PanGuLuceneHelper() { }

        #region 单一实例
        private static PanGuLuceneHelper _instance = null;
        /// <summary>
        /// 单一实例
        /// </summary>
        public static PanGuLuceneHelper instance
        {
            get
            {
                if (_instance == null) _instance = new PanGuLuceneHelper();
                return _instance;
            }
        }
        #endregion

        #region 分词测试
        /// <summary>
        /// 分词测试
        /// </summary>
        /// <param name="keyword"></param>
        /// <returns></returns>
        public string Token(string keyword)
        {
            string ret = "";
            System.IO.StringReader reader = new System.IO.StringReader(keyword);
            Lucene.Net.Analysis.TokenStream ts = analyzer.TokenStream(keyword, reader);
            bool hasNext = ts.IncrementToken();
            Lucene.Net.Analysis.Tokenattributes.ITermAttribute ita;
            while (hasNext)
            {
                ita = ts.GetAttribute<Lucene.Net.Analysis.Tokenattributes.ITermAttribute>();
                ret += ita.Term + "|";
                hasNext = ts.IncrementToken();
            }
            ts.CloneAttributes();
            reader.Close();
            analyzer.Close();
            return ret;
        }
        #endregion

        #region 创建索引
        /// <summary>
        /// 创建索引
        /// </summary>
        /// <param name="datalist">数据</param>
        /// <param name="indexAdd">false表示追加(true表示删除之前的重新写入),注意ID唯一</param>
        /// <returns></returns>
        public bool CreateIndex(List<MySearchUnit> datalist, bool indexAdd)
        {
            IndexWriter writer = null;
            try
            {
                writer = new IndexWriter(directory_luce, analyzer, indexAdd, IndexWriter.MaxFieldLength.LIMITED);//false表示追加(true表示删除之前的重新写入)
            }
            catch
            {
                writer = new IndexWriter(directory_luce, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);//false表示追加(true表示删除之前的重新写入)
            }
            foreach (MySearchUnit data in datalist)
            {
                CreateIndex(writer, data);
            }
            writer.Optimize();
            writer.Dispose();
            return true;
        }

        /// <summary>
        /// 创建索引
        /// </summary>
        /// <param name="datalist"></param>
        /// <returns></returns>
        public bool CreateIndex(List<MySearchUnit> datalist)
        {
            IndexWriter writer = null;
            try
            {
                writer = new IndexWriter(directory_luce, analyzer, false, IndexWriter.MaxFieldLength.LIMITED);//false表示追加(true表示删除之前的重新写入)
            }
            catch
            {
                writer = new IndexWriter(directory_luce, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);//false表示追加(true表示删除之前的重新写入)
            }
            foreach (MySearchUnit data in datalist)
            {
                CreateIndex(writer, data);
            }
            writer.Optimize();
            writer.Dispose();
            return true;
        }

        public bool CreateIndex(IndexWriter writer, MySearchUnit data)
        {
            try
            {

                if (data == null) return false;
                Document doc = new Document();
                Type type = data.GetType();//assembly.GetType("Reflect_test.PurchaseOrderHeadManageModel", true, true); //命名空间名称 + 类名    

                //创建类的实例    
                //object obj = Activator.CreateInstance(type, true);  
                //获取公共属性    
                PropertyInfo[] Propertys = type.GetProperties();
                for (int i = 0; i < Propertys.Length; i++)
                {
                    //Propertys[i].SetValue(Propertys[i], i, null); //设置值
                    PropertyInfo pi = Propertys[i];
                    string name = pi.Name;
                    object objval = pi.GetValue(data, null);
                    string value = objval == null ? "" : objval.ToString(); //值
                    if (name == "id" || name == "flag")//id在写入索引时必是不分词,否则是模糊搜索和删除,会出现混乱
                    {
                        doc.Add(new Field(name, value, Field.Store.YES, Field.Index.NOT_ANALYZED));//id不分词
                    }
                    else
                    {
                        doc.Add(new Field(name, value, Field.Store.YES, Field.Index.ANALYZED));
                    }
                }
                writer.AddDocument(doc);
            }
            catch (System.IO.FileNotFoundException fnfe)
            {
                throw fnfe;
            }
            return true;
        }
        #endregion

        #region 在title和content字段中查询数据
        /// <summary>
        /// 在title和content字段中查询数据
        /// </summary>
        /// <param name="keyword"></param>
        /// <returns></returns>
        public List<MySearchUnit> Search(string keyword)
        {

            string[] fileds = { "title", "content" };//查询字段
            //Stopwatch st = new Stopwatch();
            //st.Start();
            QueryParser parser = null;// new QueryParser(Lucene.Net.Util.Version.LUCENE_30, field, analyzer);//一个字段查询
            parser = new MultiFieldQueryParser(version, fileds, analyzer);//多个字段查询
            Query query = parser.Parse(keyword);
            int n = 1000;
            IndexSearcher searcher = new IndexSearcher(directory_luce, true);//true-表示只读
            TopDocs docs = searcher.Search(query, (Filter)null, n);
            if (docs == null || docs.TotalHits == 0)
            {
                return null;
            }
            else
            {
                List<MySearchUnit> list = new List<MySearchUnit>();
                int counter = 1;
                foreach (ScoreDoc sd in docs.ScoreDocs)//遍历搜索到的结果
                {
                    try
                    {
                        Document doc = searcher.Doc(sd.Doc);
                        string id = doc.Get("id");
                        string title = doc.Get("title");
                        string content = doc.Get("content");
                        string flag = doc.Get("flag");
                        string imageurl = doc.Get("imageurl");
                        string updatetime = doc.Get("updatetime");

                        string createdate = doc.Get("createdate");
                        PanGu.HighLight.SimpleHTMLFormatter simpleHTMLFormatter = new PanGu.HighLight.SimpleHTMLFormatter("<font color=\"red\">", "</font>");
                        PanGu.HighLight.Highlighter highlighter = new PanGu.HighLight.Highlighter(simpleHTMLFormatter, new PanGu.Segment());
                        highlighter.FragmentSize = 50;
                        content = highlighter.GetBestFragment(keyword, content);
                        string titlehighlight = highlighter.GetBestFragment(keyword, title);
                        if (titlehighlight != "") title = titlehighlight;
                        list.Add(new MySearchUnit(id, title, content, flag, imageurl, updatetime));
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                    counter++;
                }
                return list;
            }
            //st.Stop();
            //Response.Write("查询时间:" + st.ElapsedMilliseconds + " 毫秒<br/>");

        }
        #endregion

        #region 在不同的分类下再根据title和content字段中查询数据(分页)
        /// <summary>
        /// 在不同的类型下再根据title和content字段中查询数据(分页)
        /// </summary>
        /// <param name="_flag">分类,传空值查询全部</param>
        /// <param name="keyword"></param>
        /// <param name="PageIndex"></param>
        /// <param name="PageSize"></param>
        /// <param name="TotalCount"></param>
        /// <returns></returns>
        public List<MySearchUnit> Search(string _flag, string keyword, int PageIndex, int PageSize, bool Highlight, out int TotalCount)
        {
            if (PageIndex < 1) PageIndex = 1;
            //Stopwatch st = new Stopwatch();
            //st.Start();
            BooleanQuery bq = new BooleanQuery();
            if (_flag != "")
            {
                QueryParser qpflag = new QueryParser(version, "flag", analyzer);
                Query qflag = qpflag.Parse(_flag);
                bq.Add(qflag, Occur.MUST);//与运算
            }
            if (keyword != "")
            {
                string[] fileds = { "title", "content" };//查询字段
                QueryParser parser = null;// new QueryParser(version, field, analyzer);//一个字段查询
                parser = new MultiFieldQueryParser(version, fileds, analyzer);//多个字段查询
                Query queryKeyword = parser.Parse(keyword);
                bq.Add(queryKeyword, Occur.MUST);//与运算
            }

            TopScoreDocCollector collector = TopScoreDocCollector.Create(PageIndex * PageSize, false);
            IndexSearcher searcher = new IndexSearcher(directory_luce, true);//true-表示只读
            searcher.Search(bq, collector);
            if (collector == null || collector.TotalHits == 0)
            {
                TotalCount = 0;
                return null;
            }
            else
            {
                int start = PageSize * (PageIndex - 1);
                //结束数
                int limit = PageSize;
                ScoreDoc[] hits = collector.TopDocs(start, limit).ScoreDocs;
                List<MySearchUnit> list = new List<MySearchUnit>();
                int counter = 1;
                TotalCount = collector.TotalHits;
                foreach (ScoreDoc sd in hits)//遍历搜索到的结果
                {
                    try
                    {
                        Document doc = searcher.Doc(sd.Doc);
                        string id = doc.Get("id");
                        string title = doc.Get("title");
                        string content = doc.Get("content");
                        string flag = doc.Get("flag");
                        string imageurl = doc.Get("imageurl");
                        string updatetime = doc.Get("updatetime");
                        string font_0 = "";
                        string font_1 = "";
                        if (Highlight) { font_0 = "<font color=\"red\">"; font_1 = "</font>"; }
                        PanGu.HighLight.SimpleHTMLFormatter simpleHTMLFormatter = new PanGu.HighLight.SimpleHTMLFormatter(font_0, font_1);
                        PanGu.HighLight.Highlighter highlighter = new PanGu.HighLight.Highlighter(simpleHTMLFormatter, new PanGu.Segment());
                        highlighter.FragmentSize = 50;
                        content = highlighter.GetBestFragment(keyword, content);
                        string titlehighlight = highlighter.GetBestFragment(keyword, title);
                        if (titlehighlight != "") title = titlehighlight;
                        list.Add(new MySearchUnit(id, title, content, flag, imageurl, updatetime));
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                    counter++;
                }
                return list;
            }
            //st.Stop();
            //Response.Write("查询时间:" + st.ElapsedMilliseconds + " 毫秒<br/>");

        }
        #endregion

        #region 删除索引数据(根据id)
        /// <summary>
        /// 删除索引数据(根据id)
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool Delete(string id)
        {
            bool IsSuccess = false;
            Term term = new Term("id", id);
            //Analyzer analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30);
            //Version version = new Version();
            //MultiFieldQueryParser parser = new MultiFieldQueryParser(version, new string[] { "name", "job" }, analyzer);//多个字段查询
            //Query query = parser.Parse("小王");

            //IndexReader reader = IndexReader.Open(directory_luce, false);
            //reader.DeleteDocuments(term);
            //Response.Write("删除记录结果: " + reader.HasDeletions + "<br/>");
            //reader.Dispose();

            IndexWriter writer = new IndexWriter(directory_luce, analyzer, false, IndexWriter.MaxFieldLength.LIMITED);
            writer.DeleteDocuments(term); // writer.DeleteDocuments(term)或者writer.DeleteDocuments(query);
            writer.DeleteAll();
            writer.Commit();
            //writer.Optimize();//
            IsSuccess = writer.HasDeletions();
            writer.Dispose();
            return IsSuccess;
        }
        #endregion

        #region 删除全部索引数据
        /// <summary>
        /// 删除全部索引数据
        /// </summary>
        /// <returns></returns>
        public bool DeleteAll()
        {
            bool IsSuccess = true;
            try
            {
                IndexWriter writer = new IndexWriter(directory_luce, analyzer, false, IndexWriter.MaxFieldLength.LIMITED);
                writer.DeleteAll();
                writer.Commit();
                //writer.Optimize();//
                IsSuccess = writer.HasDeletions();
                writer.Dispose();
            }
            catch
            {
                IsSuccess = false;
            }
            return IsSuccess;
        }
        #endregion

        #region directory_luce
        private Lucene.Net.Store.Directory _directory_luce = null;
        /// <summary>
        /// Lucene.Net的目录-参数
        /// </summary>
        public Lucene.Net.Store.Directory directory_luce
        {
            get
            {
                if (_directory_luce == null) _directory_luce = Lucene.Net.Store.FSDirectory.Open(directory);
                return _directory_luce;
            }
        }
        #endregion

        #region directory
        private System.IO.DirectoryInfo _directory = null;
        /// <summary>
        /// 索引在硬盘上的目录
        /// </summary>
        public System.IO.DirectoryInfo directory
        {
            get
            {
                if (_directory == null)
                {
                    string dirPath = AppDomain.CurrentDomain.BaseDirectory + "SearchIndex";
                    if (System.IO.Directory.Exists(dirPath) == false) _directory = System.IO.Directory.CreateDirectory(dirPath);
                    else _directory = new System.IO.DirectoryInfo(dirPath);
                }
                return _directory;
            }
        }
        #endregion

        #region analyzer
        private Analyzer _analyzer = null;
        /// <summary>
        /// 分析器
        /// </summary>
        public Analyzer analyzer
        {
            get
            {
                //if (_analyzer == null)
                {
                    _analyzer = new Lucene.Net.Analysis.PanGu.PanGuAnalyzer();//
                    //_analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30);
                }
                return _analyzer;
            }
        }
        #endregion

        #region version
        private static Lucene.Net.Util.Version _version = Lucene.Net.Util.Version.LUCENE_30;
        /// <summary>
        /// 版本号枚举类
        /// </summary>
        public Lucene.Net.Util.Version version
        {
            get
            {
                return _version;
            }
        }
        #endregion
    }

    #region 索引的一个行单元,相当于数据库中的一行数据
    /// <summary>
    /// 索引的一个行单元,相当于数据库中的一行数据
    /// </summary>
    public class MySearchUnit
    {
        public MySearchUnit(string _id, string _title, string _content, string _flag, string _imageurl, string _updatetime)
        {
            this.id = _id;
            this.title = _title;
            this.content = _content;
            this.flag = _flag;
            this.imageurl = _imageurl;
            this.updatetime = _updatetime;
        }
        /// <summary>
        /// 唯一的id号
        /// </summary>
        public string id { get; set; }
        /// <summary>
        /// 标题
        /// </summary>
        public string title { get; set; }
        /// <summary>
        /// 内容
        /// </summary>
        public string content { get; set; }
        /// <summary>
        /// 其他信息
        /// </summary>
        public string flag { get; set; }
        /// <summary>
        /// 图片路径
        /// </summary>
        public string imageurl { get; set; }
        /// <summary>
        /// 时间
        /// </summary>
        public string updatetime { get; set; }
    }
    #endregion
}




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值