前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >使用Lucene.net创建索引,实现搜索的C#代码示例

使用Lucene.net创建索引,实现搜索的C#代码示例

原创
作者头像
用户7705674
修改于 2021-11-02 08:09:59
修改于 2021-11-02 08:09:59
1.1K00
代码可运行
举报
文章被收录于专栏:css小迷妹css小迷妹
运行总次数:0
代码可运行
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Lucene.Net.Store;
using Lucene.Net.Analysis;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Index;
using Lucene.Net.Documents;
using Lucene.Net.Search;
using Lucene.Net.QueryParsers;
using System.Diagnostics;

namespace LuceneNet.Web.Controllers {
    public class HomeController : Controller {
        public ActionResult Index() {
            ViewBag.Message = "欢迎使用 ASP.NET MVC!";
            return View();
        }
        public ActionResult About() {
            return View();
        }
        /// <summary>
        /// 添加索引
        /// </summary>
        /// <returns></returns>
        public ActionResult AddIndex() {
            //为索引存储目录
            string INDEX_STORE_PATH = Server.MapPath("~/SearchIndex");
#if DEBUG
            ///如果存在文件则删除(测试用)
            if (System.IO.Directory.Exists(INDEX_STORE_PATH)) {
                System.IO.Directory.Delete(INDEX_STORE_PATH, true);
            }
#endif
            Directory indexDirectory = FSDirectory.Open(new System.IO.DirectoryInfo(INDEX_STORE_PATH));
            Analyzer analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29);
            IndexWriter writer = null;

            try {
                //检查索引文件是否存在
                bool iscreate = !Lucene.Net.Index.IndexReader.IndexExists(indexDirectory);
                //如果索引文件不存在则创建索引文件,否则创建索引文件
                writer = new IndexWriter(indexDirectory, analyzer, iscreate, IndexWriter.MaxFieldLength.UNLIMITED);

                //开始添加索引
                foreach (var item in Get()) {
                    Document doc = new Document();
                    doc.Add(new Field("id", item.Id, Field.Store.YES, Field.Index.ANALYZED));//存储,不分词索引
                    doc.Add(new Field("classid", item.ClassId, Field.Store.YES, Field.Index.NOT_ANALYZED));//存储,不分词索引
                    doc.Add(new Field("classname", item.ClassName, Field.Store.YES, Field.Index.ANALYZED));//存储,不分词索引
                    doc.Add(new Field("title", item.Title, Field.Store.YES, Field.Index.ANALYZED));//存储,分词索引
                    doc.Add(new Field("summary", item.Summary, Field.Store.YES, Field.Index.ANALYZED));//存储,分词索引
                    doc.Add(new Field("createtime", item.CreateTime.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));//存储,分词索引
                    writer.AddDocument(doc);
                }
                writer.Optimize();
            } catch (Exception) {
                throw;
            } finally {
                if (analyzer != null)
                    analyzer.Close();
                if (writer != null)
                    writer.Close();
                if (indexDirectory != null)
                    indexDirectory.Close();
            }
            return RedirectToAction("index");
        }
        /// <summary>
        /// 搜索
        /// </summary>
        /// <param name="k"></param>
        /// <param name="cid"></param>
        /// <returns></returns>
        public ActionResult Search(string k, string cid) {
            Stopwatch st = new Stopwatch();
            st.Start();//计时开始  
            //为索引存储目录
            string INDEX_STORE_PATH = Server.MapPath("~/SearchIndex");
            var ver = Lucene.Net.Util.Version.LUCENE_29;
            Directory indexDirectory = FSDirectory.Open(new System.IO.DirectoryInfo(INDEX_STORE_PATH));
            Analyzer analyzer = new StandardAnalyzer(ver);
            IndexSearcher searcher = null;
            List<Article> list;
            int recCount = 0;
            try {
                searcher = new IndexSearcher(indexDirectory, true);
                string[] fields = { "title", "summary" };
                BooleanQuery booleanQuery = new BooleanQuery();
                //多字段查询同时搜索title和summary
                MultiFieldQueryParser parser = new MultiFieldQueryParser(ver, fields, analyzer);
                Query query = parser.Parse(k);
                //Query query1 = new QueryParser(ver, "classid", analyzer).Parse("1");

                //TermQuery只能查询不分词的索引(Field.Index.NOT_ANALYZED)
                Query query1 = new TermQuery(new Term("id", "1"));
                //当classname为ANALYZED时搜不到
                // Query query2 = new TermQuery(new Term("classname", "体育新闻"));
                //只有当classname为NOT_ANALYZED才可以搜得到,
                //由此得出TermQuery只能查询不分词的索引(Field.Index.NOT_ANALYZED)的结论
                //但当id为ANALYZED时TermQuery却可以收的到,
                //当搜classname中包含“体”时即Query query2 = new TermQuery(new Term("classname", "体"));
                //当搜classname中包含“育”时即Query query2 = new TermQuery(new Term("classname", "育"));
                //可以搜得到。因此,由此得出,TermQuery搜的是最小单位,由此又得出Lucene是把“体育新闻”拆分成了"体/育/新/闻"四部分
                //听说Lucene分词是按空格分的,那么把“体育新闻”,改成“体育 新闻”后再重新生成索引是不是可以搜的到呢?
                //Query query2 = new TermQuery(new Term("classname", "体育"));
                //但是结果却是搜不到,纳闷...难道Lucene的分词不是这么分而是更复杂?
                //StandardAnalyzer看来是对中文分词不怎么好,当ClassName = "sports news"可以搜sports和news
                //StandardAnalyzer只支持英文的空格分词
                Query query2 = new TermQuery(new Term("classname", k));
                //关于QueryParser的搜索当k为Empty或null时会报错注意处理
                //Query query3 = new QueryParser(ver, "title", analyzer).Parse(k);
                Query query3 = new QueryParser(ver, "title", analyzer).Parse(k);

                Query query4 = new PrefixQuery(new Term("classname", k));
                Query query5 = new QueryParser(ver, "title", analyzer).Parse(k);
                TermRangeQuery query6 = new TermRangeQuery("createtime", "2012-1-3", "2012-5-3", true, true);

                //booleanQuery.Add(query1, BooleanClause.Occur.MUST);
                //booleanQuery.Add(query2, BooleanClause.Occur.MUST);
                //booleanQuery.Add(query3, BooleanClause.Occur.MUST);
                booleanQuery.Add(query4, BooleanClause.Occur.MUST);
                //booleanQuery.Add(query5, BooleanClause.Occur.MUST);
                booleanQuery.Add(query6, BooleanClause.Occur.MUST);
                TopDocs ts = searcher.Search(booleanQuery, null, 100);//执行搜索,获取查询结果集对象

                recCount = ts.totalHits;//获取命中的文档个数
                ScoreDoc[] hits = ts.scoreDocs;//获取命中的文档信息对象
                st.Stop();//计时停止
                ViewBag.EvenTime = string.Format("{0}毫秒,生成的Query语句:{1}", st.ElapsedMilliseconds, booleanQuery.ToString());
                ViewBag.Count = recCount;
                list = new List<Article>();
                foreach (var item in hits) {
                    list.Add(new Article()
                    {
                        Id = searcher.Doc(item.doc).Get("id"),
                        ClassId = searcher.Doc(item.doc).Get("classid"),
                        ClassName = searcher.Doc(item.doc).Get("classname"),
                        Title = searcher.Doc(item.doc).Get("title"),
                        Summary = searcher.Doc(item.doc).Get("summary"),
                        Score = item.score.ToString(),
                        CreateTime = DateTime.Parse(searcher.Doc(item.doc).Get("createtime"))
                    });
                }
            } catch (Exception) {
                throw;
            } finally {
                if (searcher != null) {
                    searcher.Close();
                }
            }

            return View(list);
        }

        public List<Article> Get() {
            List<Article> list = new List<Article>();
            list.Add(new Article() { Id = "1", ClassId = "1", ClassName = "体育新闻", Title = "微软发布MVC4.0了", Summary = "微软发布MVC4.0了,此版本更加强大", CreateTime = DateTime.Parse("2012-2-3") });
            list.Add(new Article() { Id = "2", ClassId = "1", ClassName = "IT新闻", Title = "跟谷歌测试工程师的对话", Summary = "本文主人公Alan是谷歌的一名的软件测试工程师,他的工作对象是谷歌的DoubleClick广告管理系统(Bid Manager),这个系统提供让广告代理商和广告客户在多个广告上进行报价竞标的功能。", CreateTime = DateTime.Parse("2012-3-3") });
            list.Add(new Article() { Id = "3", ClassId = "1", ClassName = "体育 新闻", Title = "好的程序员应该熟悉的几门编程语言", Summary = "如果想成为一个好的程序员,甚至架构师、技术总监等,显然只精通一种编程语言是不够的,还应该在常见领域学会几门编程语言,正如我们要成为高级人才不仅要会中文还要会英文", CreateTime = DateTime.Parse("2012-4-3") });
            list.Add(new Article() { Id = "4", ClassId = "2", ClassName = "娱乐新闻", Title = "Javascript开发《三国志曹操传》-开源讲座(五)-可移动地图的实现", Summary = "这一讲的内容很简单,大家理解起来会更快。因此我只对重点加以分析,其他的就轮到大家思考哦!首先来说,我对游戏开发可以算是不怎么深入,因为现在的程序员爱用canvas,我却就只会拿几个div凑和。", CreateTime = DateTime.Parse("2012-5-3") });
            list.Add(new Article() { Id = "5", ClassId = "2", ClassName = "体育新闻", Title = "Android之BaseExpandableListAdapter使用心得", Summary = " 但是我最近做那个QQ项目是遇到一个问题,如果给这个ExpandableListView添加动态从网上获取的数据呢?前面跟大家分享的时候,是用了静态的数据,很好处理。", CreateTime = DateTime.Parse("2012-6-3") });
            list.Add(new Article() { Id = "6", ClassId = "3", ClassName = "sports news", Title = "对话CSDN蒋涛:微软移动互联网马太效应不可避免,小团队需学会利用平台", Summary = "CSDN是全球最大的中文IT社区,也是雷锋网最重要的合作伙伴之一,自1999年创办至今,有着非常强大的业界影响力和号召力,其专注IT信息传播、技术交流、教育培训和专业技术人才服务,在2012年移动开发者大会即将举办之际,雷锋网对CSDN的掌门人蒋涛做了一次专访,一起探讨移动互联网的新技术浪潮和下一波发展趋势。", CreateTime = DateTime.Parse("2012-7-3") });
            list.Add(new Article() { Id = "7", ClassId = "3", ClassName = "体育新闻", Title = "基于MySQL的分布式事务控制方案", Summary = "基于MySQL的分布式事务控制方案", CreateTime = DateTime.Parse("2012-8-3") });
            list.Add(new Article() { Id = "8", ClassId = "4", ClassName = "sports news", Title = "IOS和Android开发的一些个人感受", Summary = "最近公司的产品 Android版本第二版也算到了收尾,新加了几个功能性模块,我基本也就捡了几个好玩的模块做了下。", CreateTime = DateTime.Parse("2012-9-3") });
            list.Add(new Article() { Id = "9", ClassId = "5", ClassName = "IT资讯", Title = "Google Code的简单使用", Summary = "google code简介:用于管理代码的仓库,反正我是这么理解的。就比我们在公司的时候也会有个用于存放公司代码的主机一样,google同样给我们提供了这样的一个host。这样我们可以在不同电脑不同地方随时的checkout,commit,同时分享我们的项目。", CreateTime = DateTime.Parse("2012-10-3") });
            list.Add(new Article() { Id = "10", ClassId = "33", ClassName = "IT资讯", Title = "谷歌在印度推Gmail免费短信服务", Summary = "歌一直在努力桥接发展中国家功能手机SMS服务和Gmail之间的服务,这不,近日谷歌在印度推出“Gmail SMS”服务,这使得印度的Gmail用户可以从Gmail的窗口发送信息到手机上并且接受聊天信息的回复,目前谷歌的这项服务已经得到印度的八大运营商的支持。", CreateTime = DateTime.Parse("2012-11-3") });
            list.Add(new Article() { Id = "11", ClassId = "11", ClassName = "体育新闻", Title = "鲍尔默:微软新时代 软硬结合“赢”未来", Summary = "微软CEO鲍尔默在年度公开信中表示,微软在未来将紧密结合硬件和软件。鲍尔默认为,这是微软的一个新时代。“我们看到了前所未有的机会,我们对此很兴奋,并且保持着乐观的心态。”", CreateTime = DateTime.Parse("2012-12-3") });
            return list;
        }
    }

    public class Article {
        public string Id { get; set; }
        public string ClassId { get; set; }
        public string ClassName { get; set; }
        public string Title { get; set; }
        public string Summary { get; set; }
        public string Score { get; set; }
        public DateTime CreateTime { get; set; }
    }
} 

这段例子代码用的Lucene.Net2.9.2版本。现在最新版本是Lucene.Net3.0;Lucene.Net可以使用NuGet的安装得到

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
lucene.net全文检索(二)lucene.net 的封装
明志德道
2023/10/21
2990
lucene.net全文检索(一)相关概念及示例
站内搜索通俗来讲是一个网站或商城的“大门口”,一般在形式上包括两个要件:搜索入口和搜索结果页面,但在其后台架构上是比较复杂的,其核心要件包括:中文分词技术、页面抓取技术、建立索引、对搜索结果排序以及对搜索关键词的统计、分析、关联、推荐等。
明志德道
2023/10/21
3320
lucene.net全文检索(一)相关概念及示例
lucene6 搜索按照字符串字段排序
这里给出一个demo,希望帮到有需要的朋友,下面这个实例是以图书馆记录图书为原型设计,
johnhuster的分享
2022/03/28
3470
一个朴素的搜索引擎实现
今天我们要使用 Lucene 来实现一个简单的搜索引擎,我们要使用上一节爬取的果壳网语料库来构建索引,然后在索引的基础上进行关键词查询。
老钱
2019/09/11
5400
一个朴素的搜索引擎实现
lucene6按照整形数据排序搜索结果
lucene6跟早期版本有蛮大的区别,这里给出一个按照整形排序的例子,希望帮到有需要的小伙伴:
johnhuster的分享
2022/03/29
3860
lucene思维导图,让搜索引擎不再难懂
以上是我们java常用的全文搜索引擎框架,很多项目的搜索功能都是基于以上4个框架完成的。
java思维导图
2018/12/21
1.5K0
lucene思维导图,让搜索引擎不再难懂
Lucene:Grouping组查询
lucene的联想词是在org.apache.lucene.lucene-grouping包下边,提供了组查询功能的支持。
HLee
2020/12/31
2.2K0
Lucene:Grouping组查询
使用Lucene.Net做一个简单的搜索引擎-全文索引
Lucene.net是Lucene的.net移植版本,是一个开源的全文检索引擎开发包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎。
Mr. Wei
2020/02/29
1.1K0
使用Lucene.Net做一个简单的搜索引擎-全文索引
借助 Lucene.Net 构建站内搜索引擎(下)
前言:上一篇我们学习了Lucene.Net的基本概念、分词以及实现了一个最简单的搜索引擎,这一篇我们开始开发一个初具规模的站内搜索项目,通过开发站内搜索模块,我们可以方便地在项目中集成站内搜索功能。本次示例Demo麻雀虽小,五脏俱全,值得学习。
Edison Zhou
2018/08/21
1.4K0
借助 Lucene.Net 构建站内搜索引擎(下)
大数据组件:Lucene全文索引与搜索
Lucene是一款高性能、可扩展的信息检索工具库,是用于全文检索和搜寻的Java开放源码程序库,最初是由Doug Cutting所撰写,2000年发行了第一个开源版本,2005年成为Apache顶级项目。虽然经过近20年,Lucene在全文检索领域还是独领风骚,蓬勃发展。
Yiwenwu
2024/05/25
4430
大数据组件:Lucene全文索引与搜索
Lucene 全文检索
全文检索就是先分词创建索引,再执行搜索的过程。分词就是将一段文字分成一个个单词。全文检索就将一段文字分成一个个单词去查询数据
Carlos Ouyang
2019/08/19
1.7K0
Lucene 全文检索
Lucene.Net实现站内搜索功能
Lucene.net是Lucene的.net移植版本,是一个开源的全文检索引擎开发包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎。开发人员可以基于Lucene.net实现全文检索的功能。
做全栈攻城狮
2018/12/20
1.1K0
Spring Boot中集成Lucene(十一)
大家好,我是默语,一个专注于技术分享的博主。今天我们来探讨 Spring Boot中集成Lucene 的话题。在大数据时代,海量文本数据的高效检索变得尤为重要。Apache Lucene 是一个高性能、可扩展的全文搜索库,可以帮助我们快速建立索引并进行搜索。在这篇文章中,我们将深入探讨Lucene的基本概念,如何在Spring Boot项目中集成Lucene,并通过代码示例展示中文分词检索和高亮显示的实现。通过这篇文章,您将掌握Spring Boot与Lucene集成的关键技术,提升应用的搜索功能。让我们开始吧!🚀
默 语
2024/11/20
2490
Spring Boot 中使用 Java API 调用 lucene
Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎 全文检索概述 比如,我们一个文件夹中,或者一个磁盘中有很多的文件,记事本、world、Excel、pdf,我们想根据其中的
程序员鹏磊
2018/02/09
2.8K0
Spring Boot 中使用  Java API 调用 lucene
要飞起来了,Lucene 高阶查询技巧
在前面的章节中我们使用了最基础的关键词查询 TermQuery 和 复合查询 BooleanQuery,本节我们来尝试 Lucene 内置的其它高级查询功能。
老钱
2019/09/17
1.4K0
要飞起来了,Lucene 高阶查询技巧
Lucene全文检索
全文检索是程序开发中非常重要的一个应用,今天带大家来一起学习Java基于Lucene的全文检索机制。 全文检索的概念 1) 从大量的信息中快速、准确地查找出要的信息。 2) 搜索的内容是文本信息(不是多媒体)。 3) 搜索的方式:不是根据语句的意思进行处理。如果要搜索的文本为"西安",那么含有这些词(西安程序员、西安)就能搜索出来。每一个词都是关键词。 4) 全面、快速、准确是衡量全文检索系统的关键指标。 5) 概括: a) 只处理文本。 b) 不处理语义。 a) 搜索时英文不区分大小写。 b) 结果列表
南风
2018/07/02
1.5K0
Apache Lucene全局搜索引擎入门教程
Lucene搜索的API类主要有4个 IndexSearch,Query,QueryParser,Hits
SmileNicky
2019/01/17
2.8K0
Lucene的全文检索学习
Lucene的官方网站(Apache的顶级项目):http://lucene.apache.org/
别先生
2019/10/13
9930
借助 Lucene.Net 构建站内搜索引擎(上)
前言:最近翻开了之前老杨(杨中科)的Lucene.Net站内搜索项目的教学视频,于是作为老杨脑残粉的我又跟着复习了一遍,学习途中做了一些笔记也就成了接下来您看到的这篇博文,仅仅是我的个人笔记,大神请呵呵一笑而过。相信做过站内搜索的.Net程序员应该对Lucene.Net不陌生,没做过的也许会问:就不是个查询嘛!为什么不能使用Like模糊查找呢?原因很简单:模糊查询的契合度太低,匹配关键字之间不能含有其他内容。最重要的是它会造成数据库全表扫描,效率低下,即使使用视图,也会造成数据库服务器"亚历山大"!因此,有必要了解一下Lucene.Net这个神器(也许现在早已不是)!
Edison Zhou
2018/08/20
1.1K0
借助 Lucene.Net 构建站内搜索引擎(上)
Lucene 7.4 初体验
Lucene是目前最流行的Java开源搜索引擎类库,最新版本为7.4.0。Lucene通常用于全文检索,Lucene具有简单高效跨平台等特点,因此有不少搜索引擎都是基于Lucene构建的,例如:Elasticsearch,Solr等等。
小旋锋
2019/01/21
6270
相关推荐
lucene.net全文检索(二)lucene.net 的封装
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验