• Solr学习总结(六)SolrNet的高级用法(复杂查询,分页,高亮,Facet查询)


            上一篇,讲到了SolrNet的基本用法及CURD,这个算是SolrNet 的入门知识介绍吧,昨天写完之后,有朋友评论说,这些感觉都被写烂了。没错,这些基本的用法,在网上百度,资料肯定一大堆,有一些写的肯定比我的好,不过,这个是Solr系列文章,会从Solr的基础入门讲到实际开发中的分页,高亮,Facet查询等高级用法。所以,基础的入门也会涉及一些,望大家见谅。我用这么多篇文章,来总结Solr 也是为了将Solr 的 安装,配置,开发等等,整个过程的资料,都能总结汇集到一起,这样不管是懂Solr还是不知道Solr 的人,都能按照我的文章,一步一步的学习入门。

     

            下面就来讲一讲SolrNet的高级用法(复杂查询,分页,高亮,Facet查询)。其实这些高级查询,说白了,也还是SolrNet 将Solr 的相关查询参数封装起来了,使得我们调用更加方便。但是实际上还是按照Solr 的参数规则,拼接查询参数,并向Solr 服务器发起请求。这就是所谓的万变不离其宗,这也是我前面花两篇文章,来总结Solr 的查询参数的初心。如果有兴趣可以监控SolrNet 发起的Http 请求,看看是不是按照solr 的查询参数规则来的。具体Solr的查询参数相关说明,请看这篇文章《Solr学习总结(四)Solr查询参数》

     

       示例下载:Demo下载

     

       1.复杂查询

         public static void Query(string keyword, int category, string color, double price, int start, DateTime? startTime, DateTime? endTime, int pageNum)
            {
                //定义solr
                ISolrOperations<Product> solr = ServiceLocator.Current.GetInstance<ISolrOperations<Product>>();
                QueryOptions options = new QueryOptions();//创建条件集合
                List<ISolrQuery> query = new List<ISolrQuery>();
    
                if (!string.IsNullOrEmpty(keyword))
                {
                    List<ISolrQuery> ar = new List<ISolrQuery>();
                    string[] keywords = keyword.Split(new char[] { ',' });
                    foreach (string a in keywords)
                    {
                        ar.Add(new SolrQueryByField("id", a));
                    }
                    //创建ID 条件集合的关系,是OR还是AND
                    var kw = new SolrMultipleCriteriaQuery(ar, "OR");
                    //添加至条件集合
                    query.Add(kw);
                }
    
                if (category > 0)
                {
                    // 创建分类的查询条件
                    var qCate = new SolrQueryByField("category", category.ToString());
                    //添加条件
                    query.Add(qCate);
                }
    
                //查询颜色,多个颜色,用 ,号隔开 green,grey
                if (color != "")
                {
                    //创建颜色条件集合
                    List<ISolrQuery> ar = new List<ISolrQuery>();
                    string[] colors = color.Split(new char[] { ',' });
                    foreach (string a in colors)
                    {
                        ar.Add(new SolrQueryByField("color", a));
                    }
    
                    //创建颜色查询条件的关系,是OR还是AND
                    var qcolor = new SolrMultipleCriteriaQuery(ar, "OR");
    
                    //添加至条件集合
                    query.Add(qcolor);
                }
    
                //创建时间范围条件, 开始时间和结束时间 
                SolrQueryByRange<DateTime> qDateRange = null;
                if (startTime != null && endTime != null)
                {
                    var stime = DateTime.Parse(startTime.ToString());
                    var etime = DateTime.Parse(endTime.ToString());
    
                    //后两个参数,一个是开始时间,一个是结束时时间
                    qDateRange = new SolrQueryByRange<DateTime>("updatetime", stime, etime);
                    //时间范围条件加入集合
                    query.Add(qDateRange);
                }
    
                //设定查询结果的排序,按照时间倒排序.
                options.AddOrder(new SolrNet.SortOrder("updatetime", Order.DESC));
    
                //条件集合之间的关系
                var qTBO = new SolrMultipleCriteriaQuery(query, "AND");
    
                //执行查询
                SolrQueryResults<Product> results = solr.Query(qTBO, options);
            // 显示查询结果
                foreach (Product p in results)
                {
                    Console.WriteLine("id:{0}   name:{1}   color:{2}     price:{3}", p.id, p.name, p.color, p.price);
                }
                Console.ReadKey();
            }

       说明:a. QueryOptions 查询的相关设置,分页属性,结果集排序,条件集合之间的关系(AND, OR)等。

                     b. ISolrQuery 查询条件,集合

                     c. SolrMultipleCriteriaQuery条件集合之间的关系,(AND,OR)

               

       2.分页

          分页其实也就是比查询,多设置了Rows和Start 参数。其他的和查询一致。最后返回的时候,除了返回查询结果,还要返回总页数和数据总条数

           QueryOptions options = new QueryOptions();
                //分页参数
                options.Rows = pageNum; //数据条数
                options.Start = start;  //开始项    
           // 拼接相关查询条件
           .        .
           .
    //执行查询 SolrQueryResults<Product> results = solr.Query(qTBO, options); // 得到返回的数据总条数和total和 总页数 用于分页显示, var total = results.NumFound; var pageCount = total / pageNum + 1;

       

       3.高亮  

                QueryOptions options = new QueryOptions();
           
                var high = new HighlightingParameters();
                high.Fields = new List<string> { "color" };
                high.BeforeTerm = "<font color='red'><b>";
                high.AfterTerm = "</b></font>";
    
                options.Highlight = high;
                 // 拼接其他查询条件
                .
           .
           .
            //执行查询
                SolrQueryResults<Product> results = solr.Query(qTBO, options);
            // 处理需要高亮的字段
                var highlights = results.Highlights;
                foreach (var item in results)
                {
                    var t = highlights[item.id.ToString()].Values.ToList()[0].ToList()[0];
                    item.color = t;
                }
    
                // 显示查询结果
                foreach (Product p in results)
                {
                    Console.WriteLine("id:{0}   name:{1}   color:{2}     price:{3}", p.id, p.name, p.color, p.price);
                }    

       4.Facet查询

          Facet 本书还有很多参数来限制,选择结果集。这里只介绍了几个基本的Facet用法。其他的就不一一细说。大家自己去研究吧。

          1. 普通分组,按照某个字段分组

          var facet = new FacetParameters
                    {
                        Queries = new[] { new SolrFacetFieldQuery("category") }
                    };
    
               options.Facet = facet;
    
               var qTBO = new SolrMultipleCriteriaQuery(query, "AND");
    
               SolrQueryResults<Product> results = solr.Query(qTBO, options);
    
               foreach (var f in results.FacetFields["category"])
               {
                   Console.WriteLine("{0}: {1}", f.Key, f.Value);
               }
    

          2. 时间段分组

            SolrFacetDateQuery 类里面的几个参数比较复杂。具体的可以去研究研究Date Facet 相关的参数说明。

            // 时间分组
                var facet = new FacetParameters
                {
                    Queries = new[] { 
                        new SolrFacetDateQuery(
                            "updatetime", 
                            new DateTime(2015, 11, 1) /* 开始时间 */, 
                            new DateTime(2015,12, 31) /* 结束时间 */, 
                            "+7DAY" /* 时间间隔 */) 
                        {
                            HardEnd = true,
                            Other = new[] {FacetDateOther.After, FacetDateOther.Before}
                        },
                    }
                };
    
                options.Facet = facet;
    
                //条件集合之间的关系
                var qTBO = new SolrMultipleCriteriaQuery(query, "AND");
    
                SolrQueryResults<Product> results = solr.Query(qTBO, options);
    
                DateFacetingResult dateFacetResult = results.FacetDates["updatetime"];
    
                foreach (KeyValuePair<DateTime, int> dr in dateFacetResult.DateResults)
                {
                    Console.WriteLine(dr.Key);
                    Console.WriteLine(dr.Value);
                }

          3. 任意分组 

           // 按照价格段分组
                var lessThan30 = new SolrQueryByRange<decimal>("price", 0m, 30m);
                var lessThan70 = new SolrQueryByRange<decimal>("price", 30m, 70m);
                var moreThan70 = new SolrQueryByRange<decimal>("price", 70m, 100m);
    
                var facet = new FacetParameters
                 {
                     Queries = new[] { new SolrFacetQuery(lessThan30), new SolrFacetQuery(lessThan70), new SolrFacetQuery(moreThan70) }
                 };
    
                options.Facet = facet;
    
                var qTBO = new SolrMultipleCriteriaQuery(query, "AND");
    
                SolrQueryResults<Product> results = solr.Query(qTBO, options);
                foreach (var f in results.FacetQueries)
                {
                    Console.WriteLine("{0}: {1}", f.Key, f.Value);
                }

          

          4. Pivot faceting, Pivot 这个概念还是蛮难解释的,有点类似于BI 报表中的数据钻取,即 一层一层的进行分组 统计,例如 先按颜色,分组统计,然后在统计的结果集某个子分组里面,再按照 分类 进行分组统计。 

            /// <summary>
            /// Facet 查询
            /// </summary>
            /// <param name="color"></param>
            public static void Query_FactPivot()
            {
                ISolrOperations<Product> solr = ServiceLocator.Current.GetInstance<ISolrOperations<Product>>();
                //Create a facet Pivot Query
                var facetPivotQuery = new SolrFacetPivotQuery()
                {
                    //默认是 1 pivot, 先 category 再按 color 分组
                    //如果是多个,则在后面继续追加 ,new PivotFields("color", "category")
                    Fields = new[] { new PivotFields("color", "category")},
    
                    //最小记录数
                    MinCount = 1
                };
    
                //创建一个查询参数
                //同时 pivotQueries 可以和其他查询条件一起混用
                var facetParams = new FacetParameters()
                {
                    Queries = new[] { facetPivotQuery },
    
                    Limit = 15
                };
    
                var queryOptions = new QueryOptions();
                queryOptions.Facet = facetParams;
                queryOptions.Rows = 0;
    
                var results = solr.Query("*:*", queryOptions);
                if (results.FacetPivots.Count > 0)
                {
                    foreach (var pivotTable in results.FacetPivots)
                    {
                        Console. WriteLine("Pivot table for " + pivotTable.Key);
                        foreach (var pivot in pivotTable.Value)
                        {
                            Console.WriteLine("  Pivot: " + pivot.Field + " with value " + pivot.Value + ". Child Pivots:");
                            foreach (var pivotChild in pivot.ChildPivots)
                            {
                                Console.WriteLine("    - " + pivotChild.Value + " (" + pivotChild.Count + ")");
                            }
                        }
                    }
                }
    
                Console.ReadKey();
            }      

          这个是比较精细化,也更加复杂的Facet查询。这个由于本人实际中没有用到过。所以就不在这里多讲了。感兴趣的朋友,可以去研究研究,

  • 相关阅读:
    Json 操作
    visual studio 单元测试的认识
    EntityFramework 贪婪加载与延迟加载以及资源回收
    idea 查看源码
    idea技巧快速生成构造函数 get set
    Spring Boot Jpa框架自定义查询语句返回自定义实体
    启动redis
    查找nginx安装目录并启动
    idea技巧 --查找当前方法都被哪些类引用
    第一个webapi及swagger
  • 原文地址:https://www.cnblogs.com/zhangweizhong/p/5075277.html
Copyright © 2020-2023  润新知