Lucene.Net 使用教程

    最近公司开发一个知识库系统,毫无疑问需要用到站内搜索的功能。最终选用Lucene.Net,现将项目中的一些收获和核心代码整理如下:

1. Lucene.Net是什么以及工作原理?

    Lucene.Net只是一个全文检索开发包,不是一个成型的搜索引擎,它的功能就是:把数据扔给Lucene.Net ,查询数据的时候从Lucene.Net 查询数据,可以看做是提供了全文检索功能的一个数据库。Lucene.Net不管文本数据怎么来的。用户可以基于Lucene.Net开发满足自己需求的搜索引擎。 Lucene.Net只能对文本信息进行检索。如果不是文本信息,要转换为文本信息,比如要检索Excel文件,就要用NPOI把Excel读取成字符串,然后把字符串扔给Lucene.Net。Lucene.Net会把扔给它的文本切词保存,加快检索速度。

 

 

 

 

2. 分词

     分词是核心的算法,搜索引擎内部保存的就是一个个的“词(Word)”。英文分词很简单,按照空格分隔就可以。中文则麻烦,把“北京,Hi欢迎你们大家” 拆成“北京 Hi 欢迎 你们 大家”。“the”,“,”,“和”,“啊”,“的”等对于搜索来说无意义的词一般都属于不参与分词的无意义单词(noise word)。

Lucene.Net中不同的分词算法就是不同的类。所有分词算法类都从Analyzer类继承,不同的分词算法有不同的优缺点。

(*)内置的StandardAnalyzer是将英文按照空格、标点符号等进行分词,将中文按照单个字进行分词,一个汉字算一个词即ChineseAnalyzer
(*)二元分词算法,每两个汉字算一个单词,“欢迎你们大家”会分词为“欢迎 迎你 你们 们大 大家”,网上找到的一个二元分词算法CJKAnalyzer。
(*)基于词库的分词算法,基于一个词库进行分词,可以提高分词的成功率。有庖丁解牛、盘古分词等。效率低

3. 盘古分词算法使用

    1.打开 PanGu4Lucene\ WebDemo \Bin ,将 Dictionaries 添加到项目根路径(改名为 Dict )
    2.添加对 PanGu.dll 、 PanGu.Lucene.Analyzer.dll 的引用。
    词库的编辑,使用 DictManage.exe ,对单词编辑的时候要先查找。工作的项目中要将行业单词添加到词库中,比如餐饮搜索、租房搜索、视频搜索等。
            Analyzer analyzer = new PanGuAnalyzer();
            TokenStream tokenStream = analyzer.TokenStream("", new StringReader(TextBox1.Text));
            Lucene.Net.Analysis.Token token = null;
            while ((token = tokenStream.Next()) != null)
            {
                Response.Write(token.TermText()+"<br/>");
            }

一下是上述代码运行的结果,分词的准确率还是很高的:

4 Lucene.Net应用实例  源代码

  1. 创建索引

View Code
 string indexPath = "c:/index";
            FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NativeFSLockFactory());
            bool isUpdate = IndexReader.IndexExists(directory);
            if (isUpdate)
            {
                //如果索引目录被锁定(比如索引过程中程序异常退出),则首先解锁
                if (IndexWriter.IsLocked(directory))
                {
                    IndexWriter.Unlock(directory);
                }
            }
            var writer = new IndexWriter(directory, new PanGuAnalyzer(), !isUpdate, IndexWriter.MaxFieldLength.UNLIMITED);
            var wc = new WebClient();
            wc.Encoding = Encoding.UTF8; //否则下载的是乱码

            int maxId = GetMaxId();
            for (int i = 1; i <= maxId; i++)
            {
                string url = "http://localhost:8081/showtopic-" + i + ".aspx";
                string html = wc.DownloadString(url);

                var doc = new HTMLDocumentClass();
                doc.designMode = "on"; //不让解析引擎去尝试运行javascript
                doc.IHTMLDocument2_write(html);
                doc.close();

                string title = doc.title;
                string body = doc.body.innerText; //去掉标签

                //为避免重复索引,所以先删除number=i的记录,再重新添加
                writer.DeleteDocuments(new Term("number", i.ToString()));

                var document = new Document();
                //只有对需要全文检索的字段才ANALYZED
                document.Add(new Field("number", i.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
                document.Add(new Field("title", title, Field.Store.YES, Field.Index.NOT_ANALYZED));
                document.Add(new Field("body", body, Field.Store.YES, Field.Index.ANALYZED,
                                       Field.TermVector.WITH_POSITIONS_OFFSETS));
                writer.AddDocument(document);
            }
            writer.Close();
            directory.Close(); //不要忘了Close,否则索引结果搜不到;

 2.搜索

View Code
   string indexPath = "c:/index";
            string kw = TextBox1.Text;
            FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NoLockFactory());
            IndexReader reader = IndexReader.Open(directory, true);
            var searcher = new IndexSearcher(reader);
            var query = new PhraseQuery();

            //todo:把用户输入的关键词进行拆词

            foreach (string word in CommonHelper.SplitWord(TextBox1.Text)) //先用空格,让用户去分词,空格分隔的就是词“计算机 专业”
            {
                query.Add(new Term("body", word));
            }
            //query.Add(new Term("body","计算机"));
            //query.Add(new Term("body", "专业"));

            query.SetSlop(100);
            TopScoreDocCollector collector = TopScoreDocCollector.create(1000, true);
            searcher.Search(query, null, collector);
            ScoreDoc[] docs = collector.TopDocs(0, collector.GetTotalHits()).scoreDocs;
            var listResult = new List<SearchResult>();
            for (int i = 0; i < docs.Length; i++)
            {
                int docId = docs[i].doc; //取到文档的编号(主键,这个是Lucene .net分配的)
                //检索结果中只有文档的id,如果要取Document,则需要Doc再去取
                //降低内容占用
                Document doc = searcher.Doc(docId); //根据id找Document
                string number = doc.Get("number");
                string title = doc.Get("title");
                string body = doc.Get("body");

                var result = new SearchResult();
                result.Number = number;
                result.Title = title;


                result.BodyPreview = Preview(body, TextBox1.Text);

                listResult.Add(result);
            }
            repeaterResult.DataSource = listResult;
            repeaterResult.DataBind();

3.关键字高亮

View Code
            //创建HTMLFormatter,参数为高亮单词的前后缀 
            var simpleHTMLFormatter =
                new SimpleHTMLFormatter("<font color=\"red\">", "</font>");
            //创建 Highlighter ,输入HTMLFormatter 和 盘古分词对象Semgent 
            var highlighter =
                new Highlighter(simpleHTMLFormatter,
                                new Segment());
            //设置每个摘要段的字符数 
            highlighter.FragmentSize = 100;
            //获取最匹配的摘要段 
            String bodyPreview = highlighter.GetBestFragment(keyword, body);
            return bodyPreview;

 "http://news.oceansoft.com.cn/showtopic-" + i + ".aspx";

string html = wc.DownloadString(url);

这是我从公司的内部论坛上下载页面内容,然后给这些内容建立索引。拿到代码之后需要实际情况修改

建立索引之后查询,效果如下 :

转载于:https://www.cnblogs.com/rdzzg/archive/2013/03/06/2946149.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Lucene.net 是一个开源的全文检索引擎库,它提供了一些基本的 API 来创建和维护索引,并且可以通过这些 API 来搜索索引中的文档。下面是一些使用 Lucene.net 的基本步骤: 1. 创建索引:使用 Lucene.net 的 API,可以创建一个空的索引。可以将文档添加到索引中,以便后续搜索。 2. 添加文档:使用 Lucene.net 的 API,可以将文档添加到索引中。可以为每个文档定义一个或多个字段。 3. 搜索索引:使用 Lucene.net 的 API,可以搜索索引中的文档。可以使用查询对象来指定搜索条件,例如搜索某个字段中包含特定关键字的文档。 4. 处理搜索结果:搜索结果是一组匹配查询条件的文档。可以使用 Lucene.net 的 API 来访问每个文档的字段,以便将搜索结果呈现给用户。 以下是一个简单的示例代码,可用于创建索引、添加文档和搜索索引: ``` // 创建索引 var indexDirectory = FSDirectory.Open(@"C:\myindex"); var analyzer = new StandardAnalyzer(LuceneVersion.LUCENE_48); var indexConfig = new IndexWriterConfig(LuceneVersion.LUCENE_48, analyzer); var writer = new IndexWriter(indexDirectory, indexConfig); // 添加文档 var doc = new Document(); doc.Add(new TextField("title", "Lucene.net tutorial", Field.Store.YES)); doc.Add(new TextField("content", "This is a tutorial on how to use Lucene.net for full text search.", Field.Store.YES)); writer.AddDocument(doc); // 搜索索引 var searcher = new IndexSearcher(writer.GetReader(true)); var queryParser = new QueryParser(LuceneVersion.LUCENE_48, "content", analyzer); var query = queryParser.Parse("full text search"); var topDocs = searcher.Search(query, 10); foreach (var scoreDoc in topDocs.ScoreDocs) { var doc = searcher.Doc(scoreDoc.Doc); Console.WriteLine(doc.Get("title")); } ``` 此示例创建一个名为“myindex”的索引目录,添加一个文档,然后搜索包含“full text search”关键字的文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值