你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:技术专栏 / C专栏
Lucene.Net学习 TermQuery,NumericRangeQuery,TermRangeQuery的使用(一)
 

[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.按日期查询

  推荐精品文章

·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录
·2023年10月目录
·2023年9月目录 
·2023年8月目录 

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089