程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> Lucene.Net學習 TermQuery,NumericRangeQuery,TermRangeQuery的使用(一

Lucene.Net學習 TermQuery,NumericRangeQuery,TermRangeQuery的使用(一

編輯:C#入門知識

[C#] 
/// <summary> 
/// 搜索 
/// </summary> 
/// <param name="k"></param> 
/// <param name="cid"></param> 
/// <returns></returns> 
public ActionResult Search(string k, string p, DateTime? startDate, DateTime? endDate) 

    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; 
    bool isk = !string.IsNullOrEmpty(k), 
    isp = !string.IsNullOrEmpty(p), 
    isstartdate = startDate.HasValue, 
    isenddate = endDate.HasValue; 
 
    try { 
        searcher = new IndexSearcher(indexDirectory, true); 
 
        BooleanQuery booleanQuery = new BooleanQuery(); 
        /*
         * 多字段查詢同時搜索title和summary
         */ 
        //string[] fields = { "title", "summary" }; 
        //MultiFieldQueryParser parser = new MultiFieldQueryParser(ver, fields, analyzer); 
        //Query query = parser.Parse(k); 
        //Query query1 = new QueryParser(ver, "classid", analyzer).Parse("1"); 
 
        /*
         * TermQuery搜索文檔的最小單位
         * 如果不分詞索引,只能整體都符合才能命中
         * 如classname以不分詞的形式索引
         * classname="體育新聞"
         * 你只搜體育或新聞是不能命中的,只有收體育新聞才能命中
         * TermQuery適合用來搜索Id,classname之類的索引
         */ 
        //Query query1 = new TermQuery(new Term("id", "1")); 
        //Query query2 = new TermQuery(new Term("classname", k)); 
 
        /*
         * QueryParser支持分詞索引支持類似sql語句的查詢等,
         * 搜索形式是把你輸入的關鍵字先分詞,分詞之後再拿來搜索
         * 當然由於自帶的StandardAnalyzer對中文分詞不怎麼好,
         * (經測試StandardAnalyzer對中文的分詞不會一空格來分詞)
         * 我們就拿英文搜索來說吧。
         * 例如我們輸入的關鍵字為 I love you 
         * 他會先把I love you 分詞 可能 分成 I/love/you/i love/ i love you/具體怎麼分大家可以試試看
         * 然後再拿來搜索,如果你的文檔中存在 i 或者 love 或者you都會命中
         * 注意:使用QueryParser的搜索當k為Empty或null時會報錯注意處理
         */ 
        //查詢關鍵字 
        if (isk) { 
            Query query3 = new QueryParser(ver, "title", analyzer).Parse(k); 
            booleanQuery.Add(query3, BooleanClause.Occur.MUST); 
        } 
        /*
         * NumericRangeQuery按范圍搜索,前提是搜索的字段必須是以NumericField文檔索引
         * NumericRangeQuery可以對數字、日期、時間進行范圍搜索
         * 對日期和時間搜索時,先把日期轉成數字存索引,查詢時也是把日期轉成數字再查詢,
         * 但是此種方法日期轉換比較麻煩
         */ 
        //按價格范圍搜索(對數字搜索) 
        if (isp) { 
            string[] prices = p.Split(new char[] { '_' }); 
            float min = float.Parse(prices[0]); 
            float max = prices.Length < 2 ? 10000000000.00f : float.Parse(prices[1]); 
            Query query4 = NumericRangeQuery.NewFloatRange("price", min, max, true, true); 
            booleanQuery.Add(query4, BooleanClause.Occur.MUST); 
        } 
 
        /*
         * TermRangeQuery具體什麼原理還不那麼明白,有待研究
         */ 
        //按日期范圍搜索(對日期搜索) 
        if (isstartdate || isenddate) { 
            string mindate = isstartdate ? startDate.Value.ToString("yyyy-MM-dd") 
                : DateTime.MinValue.ToString("yyyy-MM-dd"); 
            string maxdate = isenddate ? endDate.Value.ToString("yyyy-MM-dd") 
                : DateTime.Today.ToString("yyyy-MM-dd"); 
            Query query5 = new TermRangeQuery("createtime", mindate, maxdate, true, true); 
            booleanQuery.Add(query5, BooleanClause.Occur.MUST); 
        } 
 
        //如果沒有查詢關鍵字則顯示全部的數據 
        if (!isk && !isp && !isstartdate && !isenddate) { 
            Query query6 = new TermQuery(new Term("all", "all")); 
            booleanQuery.Add(query6, BooleanClause.Occur.MUST); 
        } 
 
        //執行搜索,獲取查詢結果集對象 
        TopDocs ts = searcher.Search(booleanQuery, null, 100); 
        //ts = searcher.MaxDoc(); 
 
        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"), 
                Price = float.Parse(searcher.Doc(item.doc).Get("price")), 
                //Summary = searcher.Doc(item.doc).Get("summary"), 
                Score = item.score.ToString(), 
                CreateTime = Convert.ToDateTime(searcher.Doc(item.doc).Get("createtime")) 
            }); 
        } 
    } catch (Exception) { 
        throw; 
    } finally { 
        if (searcher != null) { 
            searcher.Close(); 
        } 
    } 
 
    return View(list); 

最後效果:
1.什麼條件也不給,顯示全部

2.按日期查詢

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved