Lucene.net是Lucene的.net移植版本,是一个开源的全文检索引擎开发包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,是一个高性能、可伸缩的文本搜索引擎库。它的功能就是负责将文本数据按照某种分词算法进行切词,分词后的结果存储在索引库中,从索引库检索数据的速度非常快。Lucene.net需要有索引库,并且只能进行站内搜索。(来自百度百科)

效果图

Net Core使用Lucene.Net和盘古分词器 实现全文检索

盘古分词

如何使用

将PanGu.dIl与PanGu.Lucenet.Analyzer. dl并加入到项目中

Net Core使用Lucene.Net和盘古分词器 实现全文检索 

将Dict文件,拷贝到项目Bin文件夹里面

Net Core使用Lucene.Net和盘古分词器 实现全文检索

Net Core使用Lucene.Net和盘古分词器 实现全文检索

字典文件夹下载:https://pan.baidu.com/s/1HNiLp6bCcodN8vqlck066g 提取码: xydc

测试

Net Core使用Lucene.Net和盘古分词器 实现全文检索

 可以看到,盘古分词相对Lucene.net自带的一元分词来说,是比较好的,因为一元分词不适合进行中文检索。

一元分词是按字拆分的,比如上面一句话,使用一元分词拆分的结果是:"有","一","种","方","言","叫","做","不","老","盖","儿"。如果查找“方言”这个词,是找不到查询结果的。不符合我们的检索习惯,所以基本不使用。

拓展

上面的"不老盖儿"(河南方言),这里想组成一个词,那么需要创建"不老盖儿"词组并添加到字典里面。

使用DictManage工具:https://pan.baidu.com/s/1Yla2DBM74kSbno8cg5kvGw 提取码:tphe

解压,运行 DictManage.exe 

Net Core使用Lucene.Net和盘古分词器 实现全文检索

然后打开 Dict 文件下的 Dict.dct 文件,并添加"不老盖儿"词组

Net Core使用Lucene.Net和盘古分词器 实现全文检索

 然后查找就可以看到"不老盖儿"词组

Net Core使用Lucene.Net和盘古分词器 实现全文检索

 然后保存覆盖原有的 Dict.dct 文件

刷新页面或者重新打开页面看下效果

Net Core使用Lucene.Net和盘古分词器 实现全文检索

Demo文件说明

Net Core使用Lucene.Net和盘古分词器 实现全文检索

简单实现 

创建索引核心代码

        /// <summary>
        /// 创建索引
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("createIndex")]
        public string CreateIndex()
        {
            //索引保存位置
            var indexPath = Directory.GetCurrentDirectory() + "/Index";
            if (!Directory.Exists(indexPath)) Directory.CreateDirectory(indexPath);
            FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NativeFSLockFactory());
            if (IndexWriter.IsLocked(directory))
            {
                //  如果索引目录被锁定(比如索引过程中程序异常退出),则首先解锁
                //  Lucene.Net在写索引库之前会自动加锁,在close的时候会自动解锁
                IndexWriter.Unlock(directory);
            }
            //Lucene的index模块主要负责索引的创建
            //  创建向索引库写操作对象  IndexWriter(索引目录,指定使用盘古分词进行切词,最大写入长度限制)
            //  补充:使用IndexWriter打开directory时会自动对索引库文件上锁
            //IndexWriter构造函数中第一个参数指定索引文件存储位置;
            //第二个参数指定分词Analyzer,Analyzer有多个子类,
            //然而其分词效果并不好,这里使用的是第三方开源分词工具盘古分词;
            //第三个参数表示是否重新创建索引,true表示重新创建(删除之前的索引文件),
            //最后一个参数指定Field的最大数目。
            IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), true,
                IndexWriter.MaxFieldLength.UNLIMITED);
            var txtPath = Directory.GetCurrentDirectory() + "/Upload/Articles";
            for (int i = 1; i <= 1000; i++)
            {
                //  一条Document相当于一条记录
                Document document = new Document();
                var title = "天骄战纪_" + i + ".txt";
                var content = System.IO.File.ReadAllText(txtPath + "/" + title, Encoding.Default);
                //  每个Document可以有自己的属性(字段),所有字段名都是自定义的,值都是string类型
                //  Field.Store.YES不仅要对文章进行分词记录,也要保存原文,就不用去数据库里查一次了
                document.Add(new Field("Title", "天骄战纪_" + i, Field.Store.YES, Field.Index.NOT_ANALYZED));
                //  需要进行全文检索的字段加 Field.Index. ANALYZED
                //  Field.Index.ANALYZED:指定文章内容按照分词后结果保存,否则无法实现后续的模糊查询 
                //  WITH_POSITIONS_OFFSETS:指示不仅保存分割后的词,还保存词之间的距离
                document.Add(new Field("Content", content, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS));
                writer.AddDocument(document);
            }
            writer.Close(); // Close后自动对索引库文件解锁
            directory.Close(); //  不要忘了Close,否则索引结果搜不到
            return "索引创建完毕";
        }
View Code

相关文章: