/// <summary> /// 获取搜索结果 /// </summary> /// <param name="msg">搜索内容</param> /// <returns>搜索结果</returns> private List <ViewModelContent> GetSearchResult(string msg) { List <ViewModelContent> viewModelList = new List <ViewModelContent>(); string indexPath = @"D:\stu\DotNet\练习\BlangenOA\lucenedir"; //对用户输入的搜索条件进行拆分。 List <string> keywordList = Common.WebCommon.PanguSplitWords(msg); FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NoLockFactory()); IndexReader reader = IndexReader.Open(directory, true); IndexSearcher searcher = new IndexSearcher(reader); //添加搜索条件 PhraseQuery query = new PhraseQuery(); foreach (string keyword in keywordList) { //Abstract中含有keyword的文章 query.Add(new Term("Abstract", keyword)); } //多个查询条件的词之间的最大距离.在文章中相隔太远 也就无意义.(例如 “大学生”这个查询条件和"简历"这个查询条件之间如果间隔的词太多也就没有意义了。) query.SetSlop(100); //TopScoreDocCollector是盛放查询结果的容器 TopScoreDocCollector collector = TopScoreDocCollector.create(1000, true); //根据query查询条件进行查询,查询结果放入collector容器 searcher.Search(query, null, collector); //得到所有查询结果中的文档,GetTotalHits():表示总条数 TopDocs(300, 20);//表示得到300(从300开始),到320(结束)的文档内容.//可以用来实现分页功能 ScoreDoc[] docs = collector.TopDocs(0, collector.GetTotalHits()).scoreDocs; for (int i = 0; i < docs.Length; i++) { // //搜索ScoreDoc[]只能获得文档的id,这样不会把查询结果的Document一次性加载到内存中。降低了内存压力,需要获得文档的详细内容的时候通过searcher.Doc来根据文档id来获得文档的详细内容对象Document. int docId = docs[i].doc; //得到查询结果文档的id(Lucene内部分配的id) Document doc = searcher.Doc(docId); //找到文档id对应的文档详细信息 viewModelList.Add(new ViewModelContent() { // 取出放进字段的值 ID = Convert.ToInt32(doc.Get("ID")), Title = doc.Get("Title"), //高亮显示 Abstract = Common.WebCommon.CreateHightLight(msg, doc.Get("Abstract")) }); } //用户将搜索内容存储到明细表中 SearchDetailsBll.AddEntity(new SearchDetails() { Id = Guid.NewGuid(), KeyWords = msg, SearchDateTime = DateTime.Now }); return(viewModelList); }
private List <Models.ViewSearchContentModel> SearchBookContent() { var indexPath = @"C:\Users\Victor\Desktop\LuceneNetDir"; var kw = Common.WebCommon.GetPanGuWord(Request["txtContent"]); FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NoLockFactory()); IndexReader reader = IndexReader.Open(directory, true); IndexSearcher searcher = new IndexSearcher(reader); //搜索条件 PhraseQuery query = new PhraseQuery(); foreach (var word in kw)//先用空格,让用户去分词,空格分隔的就是词"计算机 专业" { query.Add(new Term("body", word)); } //WITH_POSITIONS_OFFSETS -> 盘古分词在建立索引的时候已经将干扰词间距记录,lucene.net只要匹配就可以了 query.Slop = 100;//多个查询条件词之间的最大距离,在文章中相隔太远也就无意义(例如 “大学生”这个查询条件和“简历”这个查询条件之间如果间隔的词太多也就没有意义了。) //TopScoreDocCollector是盛放查询结果的容器 TopScoreDocCollector collector = TopScoreDocCollector.Create(1000, true); searcher.Search(query, null, collector); //根据query查询条件进行查询,查询结果放入cllector容器 ScoreDoc[] docs = collector.TopDocs(0, collector.TotalHits).ScoreDocs; //得到所有查询结果中的文档,collector.TotalHits:表示总条数;TopDocs(300,20):表示得到300(从300开始),到320(结束)的文档内容 var list = new List <Models.ViewSearchContentModel>(); //可以用来实现分页内容 for (int i = 0; i < docs.Length; i++) { //搜索ScoreDoc[]只能获得文档的id,这样不会把查询结果的Document一次性加载到内存中。降低了内存的压力,需要获得文档的详细内容的时候通过searcher.Doc来根据文档id来获得文档的详细内容对象document int docId = docs[i].Doc; //得到查询结果文档的id(Lucene内容分配的id) Document doc = searcher.Doc(docId); //找到文档id对应的文档详细信息 list.Add(new Models.ViewSearchContentModel { Id = doc.Get("Id"), Title = doc.Get("Title"), Content = Common.WebCommon.CreateHighLight(Request["txtContent"], doc.Get("Content"))//搜索内容关键字高亮显示 }); } SearchDetailsBll.AddEntity(new SearchDetails { Id = Guid.NewGuid(), KeyWords = Request["txtContent"], SearchDateTime = DateTime.Now, }); return(list); }