当前位置:首页 > 公司荣誉 >

Lucene .NET 全文检索

编辑:北京盛典时光文化传媒有限公司时间:2017-09-04 13:31:03阅读次数:2
Lucene .NET 全文检索

近期做项目中有用到过Lucene,那个模块是由一位前端大神负责的,空闲时间我也做了个关于Lucene做全文检索的Demo,记录下来,方便以后学习。
关于Lucene的原理,网上有长篇大论的文章,有兴趣的话可以去阅读,再次我就直奔主题,站群软件,在代码中分析其原理。

1、创建索引(此处我用的是盘古分词)

注:在后台代码的第一行上加上 #define notes这样一行代码,目的是可以用外侧代码的#if,作用嘛 用过之后就很明白了,嘿嘿。

#region 创建索引 void CreateIndex(object sender, EventArgs e) /// /// 创建索引 /// /// /// private void CreateIndex(object sender, EventArgs e) { //索引存放的物理路径 //this.CreateDirectory(); //给 indexPath 赋值 FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NativeFSLockFactory()); bool isUpdate = IndexReader.IndexExists(directory); //判断索引库文件夹存在并且存在索引库特征文件 if (isUpdate) { //同时只能有一段代码对索引库进行写操作!当使用IndexWriter打开directory的时候会自动给索引库上锁。!!! //如果索引目录被锁定(比如索引过程中程序异常退出),则首先解锁 if (IndexWriter.IsLocked(directory)) //如果索引库文件被锁定了 解锁 { IndexWriter.Unlock(directory); } } //IndexWriter writer = new IndexWriter(indexPath, new PanGuAnalyzer(), !isUpdate, Lucene.Net.Index.IndexWriter.MaxFieldLength.UNLIMITED); //该方法已过时。 IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), !isUpdate, Lucene.Net.Index.IndexWriter.MaxFieldLength.UNLIMITED); IEnumerable list = bllHelper.GetAllStory(); foreach (Story story in list) { writer.DeleteDocuments(new Term("ID", story.ID.ToString())); Document document = new Document(); //一篇文章,一部小说 //要进行全文检索的字段要设置 Field.Index.ANALYZED !!!!!!!!!!!!!!!!!!!!!!!!!! document.Add(new Field("ID", story.ID.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED)); document.Add(new Field("Title", story.Title, Field.Store.YES, Field.Index.ANALYZED, Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS)); document.Add(new Field("Author", story.Author, Field.Store.YES, Field.Index.NOT_ANALYZED)); document.Add(new Field("Content", story.Content, Field.Store.YES, Field.Index.ANALYZED, Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS)); document.Add(new Field("URL", story.URL, Field.Store.YES, Field.Index.NOT_ANALYZED)); writer.AddDocument(document); } writer.Close(); directory.Close(); } #endregion

2.接下来就是搜索了

#region 搜索 IEnumerable Search(string keyWord) /// /// 搜索 /// /// 关键字 private IEnumerable Search(string keyWord) { FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NoLockFactory()); IndexReader reader = IndexReader.Open(directory, true); IndexSearcher searcher = new IndexSearcher(reader); //多条件查询 //搜索条件 PhraseQuery queryTitle = new PhraseQuery(); //把用户输入的“北京是首都”分词为“北京 是 首都”三个词,然后添加查询条件 foreach (string word in CommonHelper.SplitWords(keyWord)) { queryTitle.Add(new Term("Title", word)); } queryTitle.SetSlop(100); //多个查询条件的词之间的最大距离。在文章中相隔太远一般也就无意义 //搜索条件 PhraseQuery queryContent = new PhraseQuery(); //把用户输入的“北京是首都”分词为“北京 是 首都”三个词,然后添加查询条件 foreach (string word in CommonHelper.SplitWords(keyWord)) { queryContent.Add(new Term("Content", word)); } queryContent.SetSlop(100); //用BooleanQuery把多个查询条件拼接起来成为一个大的查询条件 BooleanQuery query = new BooleanQuery(); query.Add(queryTitle, BooleanClause.Occur.SHOULD);//可以有 query.Add(queryContent, BooleanClause.Occur.SHOULD);//可以有 #if !notes //组合关系代表的意思如下: //1、MUST和MUST表示“与”的关系,即“并集”。 //2、MUST和MUST_NOT前者包含后者不包含。 //3、MUST_NOT和MUST_NOT没意义 //4、SHOULD与MUST表示MUST,SHOULD失去意义; //5、SHOUlD与MUST_NOT相当于MUST与MUST_NOT。 //6、SHOULD与SHOULD表示“或”的概念。 #endif //create 一个存储查询结果的容器 TopScoreDocCollector collector = TopScoreDocCollector.create(1000, true); searcher.Search(query, null, collector); ScoreDoc[] docs = collector.TopDocs(0, collector.GetTotalHits()).scoreDocs; //得到所有查询结果中的文档 List list = new List(); foreach (ScoreDoc doc in docs) { int docID = doc.doc; //得到查询结果文档的id(Lucene内部分配的id) Document document = searcher.Doc(docID); //根据ID找到对应的Document Story story = new Story(); story.ID = Convert.ToInt32(document.Get("ID")); story.Title = CommonHelper.Highlight(keyWord, document.Get("Title")); story.Author = document.Get("Author"); story.Content = CommonHelper.Highlight(keyWord, document.Get("Content")); //story.Content = document.Get("Content"); story.URL = document.Get("URL"); list.Add(story); } return list; } #endregion

3.帮助类文件

3.1 BusinessHelper类

#region 根据ID获取小说 +Story GetStoryById(int id) /// /// 根据ID获取小说 /// /// ID /// public Story GetStoryById(int id) { string sql = "SELECT * FROM Story nolock WHERE Id = @Id"; using (SqlDataReader reader = SqlHelper.ExecuteDataReader(sql, new SqlParameter("@Id", id))) { if (reader.Read()) { return ToModel(reader); } else { return null; } } } #endregion #region 获取所有的小说 +IEnumerable GetAllStory() /// /// 获取所有的小说 /// /// public IEnumerable GetAllStory() { var list = new List(); string sql = "SELECT * FROM Story nolock"; using (SqlDataReader reader = SqlHelper.ExecuteDataReader(sql)) { while (reader.Read()) { list.Add(ToModel(reader)); } } return list; } #endregion #region 把SqlDataReader转换成实体 Story ToModel(SqlDataReader reader) /// /// 把SqlDataReader转换成实体 /// /// /// private Story ToModel(SqlDataReader reader) { Story story = new Story(); story.ID = (int)ToModelValue(reader, "Id"); story.Title = (string)ToModelValue(reader, "Title"); story.Author = (string)ToModelValue(reader, "Author"); story.Content = (string)ToModelValue(reader, "Content"); story.URL = (string)ToModelValue(reader, "URL"); return story; } #endregion private object ToDBValue(object value) { if (value == null) { return DBNull.Value; } else { return value; } } private object ToModelValue(SqlDataReader reader, string columnName) { if (reader.IsDBNull(reader.GetOrdinal(columnName))) { return null; } else { return reader[columnName]; } }

企业建站2800元起,携手武汉肥猫科技,做一个有见地的颜值派!更多优惠请戳:恩施网站建设 http://enshi.45qun.com

上一篇:PHP5循环 下一篇:最后一页

相关阅读