public static void search(String indexDir, String q) { Directory dir = FSDriecotry.Open(new System.IO.FileInfo(indexDir)); IndexSearcher searcher = new IndexSearcher(dir, true); QueryParser parser = new QueryParser("contents", new StandardAnalyzer(Version.LUCENE_CURRENT)); Query query = parser.Parser(q); Lucene.Net.Saerch.TopDocs hits = searher.Search(query, 10); System.Console.WriteLine("Found " + hits.totalHits + " document(s) that matched query '" + q + "':"); for (int i = 0; i < hits.scoreDocs.Length; i++) { ScoreDoc scoreDoc = hits.ScoreDoc[i]; Document doc = searcher.Doc(scoreDoc.doc); System.Console.WriteLine(doc.Get("filename")); } searcher.Close(); }
private void SearchIndex() { String q = "t_text1:random"; QueryParser parser = new QueryParser(TEST_VERSION, "t_text1", a); Query query = parser.Parse(q); IndexSearcher searcher = new IndexSearcher(dir, true); // This scorer can return negative idf -> null fragment IScorer scorer = new QueryTermScorer(query, searcher.IndexReader, "t_text1"); // This scorer doesn't use idf (patch version) //Scorer scorer = new QueryTermScorer( query, "t_text1" ); Highlighter h = new Highlighter(scorer); TopDocs hits = searcher.Search(query, null, 10); for (int i = 0; i < hits.TotalHits; i++) { Document doc = searcher.Doc(hits.ScoreDocs[i].Doc); String result = h.GetBestFragment(a, "t_text1", doc.Get("t_text1")); Console.WriteLine("result:" + result); Assert.AreEqual(result, "more <B>random</B> words for second field"); } searcher.Close(); }
/// <summary> /// 关键词多条件搜索 /// </summary> /// <param name="keyword">关键词</param> /// <param name="brand">品牌</param> /// <param name="cfid">分类</param> /// <param name="pricelimit">价格区间</param> /// <param name="store">是否有货</param> /// <param name="order">排序</param> /// <param name="recCount">总记录数</param> /// <param name="pageLen">条数</param> /// <param name="pageNo">页码</param> /// <returns>搜索结果</returns> public override JXSearchProductResult Search(RequestForm form, out int recCount) { recCount = 0; JXSearchProductResult result = new JXSearchProductResult(); IndexSearcher search = new IndexSearcher(CURR_INDEX_DIR); try { #region 搜索条件 Query query1 = null; BooleanQuery query = new BooleanQuery(); if (StringUtil.IsNatural_Number(form.queryForm.keyword)) { // 商品ID、金象码、拼音 BooleanClause.Occur[] flags = new BooleanClause.Occur[fieldsAbbr.Length]; for (int n = 0; n < fieldsAbbr.Length; n++) { flags[n] = BooleanClause.Occur.SHOULD; } query1 = MultiFieldQueryParser.Parse(Lucene.Net.Util.Version.LUCENE_29, form.queryForm.keyword, fieldsAbbr, flags, new PanGuAnalyzer(true)); query.Add(query1, BooleanClause.Occur.MUST); } else { // 关键词检索字段\t\r\n\\t BooleanClause.Occur[] flags = new BooleanClause.Occur[fields.Length]; for (int n = 0; n < fields.Length; n++) { flags[n] = BooleanClause.Occur.SHOULD; } // 转换关键词拼音 string pinyinName = PinyinUtil.ConvertToPinyin(GetKeyWordsSplitFilter(form.queryForm.keyword, new PanGuTokenizer())); // 关键词检索 // BooleanClause.Occur.MUST 表示 and // BooleanClause.Occur.MUST_NOT 表示 not // BooleanClause.Occur.SHOULD 表示 or string q = GetKeyWordsSplitBySpace(string.Format("{0} {1}", form.queryForm.keyword, pinyinName), new PanGuTokenizer()); query1 = MultiFieldQueryParser.Parse(Lucene.Net.Util.Version.LUCENE_29, q, fields, flags, new PanGuAnalyzer(true)); query.Add(query1, BooleanClause.Occur.MUST); } // 品牌 if (form.queryForm.brandIds != null && form.queryForm.brandIds.Count() > 0) { BooleanQuery tmpBQ = new BooleanQuery(); foreach (int key in form.queryForm.brandIds) { tmpBQ.Add(new TermQuery(new Term("BrandID", key.ToString())), BooleanClause.Occur.SHOULD); } query.Add(tmpBQ, BooleanClause.Occur.MUST); } // 分类 if (form.queryForm.cfid > 0) { BooleanQuery tmpBQ = new BooleanQuery(); tmpBQ.Add(new TermQuery(new Term("CFID1", form.queryForm.cfid.ToString())), BooleanClause.Occur.SHOULD); tmpBQ.Add(new TermQuery(new Term("CFID2", form.queryForm.cfid.ToString())), BooleanClause.Occur.SHOULD); tmpBQ.Add(new TermQuery(new Term("CFID3", form.queryForm.cfid.ToString())), BooleanClause.Occur.SHOULD); query.Add(tmpBQ, BooleanClause.Occur.MUST); } // 库存 if (form.queryForm.stock > 0) { query.Add(new TermQuery(new Term("Stock", "1")), BooleanClause.Occur.MUST); } // 价格区间 if (!string.IsNullOrEmpty(form.queryForm.pricelimit)) { string[] price = form.queryForm.pricelimit.Split(",".ToCharArray()); if (price.Length > 0 && double.Parse(price[1]) > 0) { query.Add(NumericRangeQuery.NewDoubleRange("TradePrice", double.Parse(price[0]), double.Parse(price[1]), true, false), BooleanClause.Occur.MUST); } } // 是否有货 Selling 是否在卖 1:在卖 0:下架 2:暂无库存 if (form.queryForm.store == 1) { query.Add(new TermQuery(new Term("Selling", form.queryForm.store.ToString())), BooleanClause.Occur.MUST); } Hits hits = search.Search(query); #endregion // 构造商品结果 result.listProductList = ProductBinding(hits, form.queryForm.keyword, form.queryForm.order, form.pageForm.page, form.pageForm.size, out recCount); #region 构造结果参数 品牌/分类 // 排除搜索条件重新搜索 if ((form.queryForm.brandIds != null && form.queryForm.brandIds.Count() > 0) || form.queryForm.cfid > 0 || form.queryForm.store == 1 || form.queryForm.order > 0 || !string.IsNullOrEmpty(form.queryForm.pricelimit)) { BooleanQuery booleanQuery = new BooleanQuery(); booleanQuery.Add(query1, BooleanClause.Occur.MUST); hits = search.Search(query); } // 构造分类、品牌结果 IList <JXSearchEntity> list = ProductParaList(hits); if (list != null) { // 品牌 result.listBrand = list.Where(g => g.typeID == 5).ToList(); // 一级分类 IList <JXSearchEntity> categoryList = list.Where(g => g.typeID == 2 && g.parentID == 0).ToList(); if (categoryList != null) { foreach (JXSearchEntity item in categoryList) { // 二级分类 item.listSubClassification = list.Where(g => g.typeID == 2 && g.parentID == item.id).ToList(); foreach (JXSearchEntity subItem in item.listSubClassification) { // 三级分类 subItem.listSubClassification = list.Where(g => g.typeID == 2 && g.parentID == subItem.id).ToList(); } } } result.listClassification = categoryList; } #endregion // 页数 result.totalPage = Convert.ToInt32(Math.Ceiling((double)recCount / form.pageForm.size)); result.resultCode = "SUCCEED"; result.resultMsg = "SUCCEED"; } catch { } finally { search.Close(); search.Dispose(); } return(result); }
private void ValidateSearcher(bool forceReopen) { EnsureIndex(); if (!forceReopen) { if (_searcher == null) { lock (Locker) { //double check if (_searcher == null) { try { _searcher = new IndexSearcher(GetLuceneDirectory(), true); } catch (IOException ex) { throw new ApplicationException("Could not create an index searcher with the supplied lucene directory", ex); } } } } else { if (_searcher.GetReaderStatus() != ReaderStatus.Current) { lock (Locker) { //double check, now, we need to find out if it's closed or just not current switch (_searcher.GetReaderStatus()) { case ReaderStatus.Current: break; case ReaderStatus.Closed: _searcher = new IndexSearcher(GetLuceneDirectory(), true); break; case ReaderStatus.NotCurrent: //yes, this is actually the way the Lucene wants you to work... //normally, i would have thought just calling Reopen() on the underlying reader would suffice... but it doesn't. //here's references: // http://stackoverflow.com/questions/1323779/lucene-indexreader-reopen-doesnt-seem-to-work-correctly // http://gist.github.com/173978 var oldReader = _searcher.GetIndexReader(); var newReader = oldReader.Reopen(true); if (newReader != oldReader) { _searcher.Close(); oldReader.Close(); _searcher = new IndexSearcher(newReader); } break; } } } } } else { //need to close the searcher and force a re-open if (_searcher != null) { lock (Locker) { //double check if (_searcher != null) { try { _searcher.Close(); } catch (IOException) { //this will happen if it's already closed ( i think ) } finally { //set to null in case another call to this method has passed the first lock and is checking for null _searcher = null; } try { _searcher = new IndexSearcher(GetLuceneDirectory(), true); } catch (IOException ex) { throw new ApplicationException("Could not create an index searcher with the supplied lucene directory", ex); } } } } } }
/// <summary> /// 关键词搜索 /// </summary> /// <param name="q">关键词</param> /// <param name="pageLen">条数</param> /// <param name="pageNo">页码</param> /// <param name="recCount">总记录数</param> /// <returns>搜索结果</returns> public override JXSearchEntityResult Search(string q, int pageLen, int pageNo, out int recCount) { IndexSearcher search = new IndexSearcher(CURR_INDEX_DIR); // 关键词检索字段 string[] fields = { "ChineseName", "PinyinName" }; BooleanClause.Occur[] flags = new BooleanClause.Occur[fields.Length]; for (int n = 0; n < fields.Length; n++) { flags[n] = BooleanClause.Occur.SHOULD; } // 关键词检索 // BooleanClause.Occur.MUST 表示 and // BooleanClause.Occur.MUST_NOT 表示 not // BooleanClause.Occur.SHOULD 表示 or q = GetKeyWordsSplitBySpace(q, new PanGuTokenizer()); Query query1 = MultiFieldQueryParser.Parse(Lucene.Net.Util.Version.LUCENE_29, q, fields, flags, new PanGuAnalyzer(true)); BooleanQuery query = new BooleanQuery(); query.Add(query1, BooleanClause.Occur.MUST); // 查询 Hits hits = search.Search(query); // 绑定 recCount = hits.Length(); // 总记录数 int i = (pageNo - 1) * pageLen; List <JXSearchEntity> result = new List <JXSearchEntity>(); while (i < recCount && result.Count < pageLen) { JXSearchEntity info = null; try { info = new JXSearchEntity(); info.id = int.Parse(hits.Doc(i).Get("KeywordID")); info.chineseName = hits.Doc(i).Get("ChineseName"); info.productCount = int.Parse(hits.Doc(i).Get("ProductCount")); info.typeID = int.Parse(hits.Doc(i).Get("TypeID")); } catch { } finally { if (info != null) { result.Add(info); } i++; } } // 关闭搜索 search.Close(); // 返回 if (result == null || result.Count <= 0) { return(null); } else { return(new JXSearchEntityResult() { listKeyword = result, totalPage = Convert.ToInt32(Math.Ceiling((double)recCount / pageLen)), resultCode = "SUCCEED", resultMsg = "SUCCEED" }); }; }
public void Dispose() { _searcher.Close(); }
public ActionResult Search(String query) { if (query == "") { return(RedirectToAction("Index")); } query = query + "~"; DateTime datastart = DateTime.Now; Directory directory = FSDirectory.Open(new System.IO.DirectoryInfo(Server.MapPath("~/Data/Index"))); IndexSearcher searcher = new IndexSearcher(directory, true); Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_29); MultiFieldQueryParser queryParser = new MultiFieldQueryParser( Version.LUCENE_29, new String[] { "Name", "Content", "Curriculum", "User", "Group", "Theme" }, analyzer ); ScoreDoc[] scoreDocs = searcher.Search(queryParser.Parse(query), 100).scoreDocs; Hits hit = searcher.Search(queryParser.Parse(query)); int total = hit.Length(); List <ISearchResult> results = new List <ISearchResult>(); Stopwatch sw = new Stopwatch(); sw.Start(); foreach (ScoreDoc doc in scoreDocs) { ISearchResult result; Document document = searcher.Doc(doc.doc); String type = document.Get("Type").ToLower(); switch (type) { case "node": Node node = new Node(); node.Id = Convert.ToInt32(document.Get("ID")); node.Name = document.Get("Name"); node.CourseId = Convert.ToInt32(document.Get("CourseID")); node.IsFolder = Convert.ToBoolean(document.Get("isFolder")); result = new NodeResult(node, _CourseService.GetCourse(node.CourseId).Name, document.Get("Content"), _CourseService.GetCourse(node.CourseId).Updated.ToString()); break; case "course": Course course = new Course(); course.Id = Convert.ToInt32(document.Get("ID")); course.Name = document.Get("Name"); result = new CourseResult(course, _CourseService.GetCourse(course.Id).Updated.ToString(), _CourseService.GetCourse(course.Id).Owner); break; case "curriculum": Curriculum curriculum = new Curriculum(); curriculum.Id = Convert.ToInt32(document.Get("ID")); curriculum.Name = document.Get("Curriculum"); result = new CurriculumResult(curriculum, _CurriculmService.GetCurriculum(curriculum.Id).Updated.ToString()); break; case "user": User user = new User(); user.Id = Guid.Parse(document.Get("ID")); user.Name = document.Get("User"); /*user.RoleId = Convert.ToInt32(document.Get("RoleId"));*/ result = new UserResult(user); break; case "group": Group group = new Group(); group.Id = int.Parse(document.Get("ID")); group.Name = document.Get("Group"); result = new GroupResult(group); break; case "theme": Theme theme = new Theme(); theme.Id = Convert.ToInt32(document.Get("ID")); theme.Name = document.Get("Theme"); theme.CourseRef = Convert.ToInt32(document.Get("CourseRef")); result = new ThemeResult(theme, _CourseService.GetCourse(theme.CourseRef.Value).Name); break; default: throw new Exception("Unknown result type"); } results.Add(result); } sw.Stop(); DateTime dataend = DateTime.Now; analyzer.Close(); searcher.Close(); directory.Close(); ViewData["SearchString"] = query; ViewData["score"] = Math.Abs(dataend.Millisecond - datastart.Millisecond); //sw.ElapsedMilliseconds.ToString(); ViewData["total"] = total; return(View(results)); }