zoukankan      html  css  js  c++  java
  • 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查询。这个由于本人实际中没有用到过。所以就不在这里多讲了。感兴趣的朋友,可以去研究研究,

  • 相关阅读:
    java.lang.NoSuchMethodError
    asm相关内容想下载(包括 jar 包)
    Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/objectweb/asm/Type
    用Navicat连接mysql报错:2003-Can't connect to MySql server on '10.100.0.109'(10039)
    The type java.lang.reflect.AnnotatedElement cannot be resolved. It is indirectly referenced from required .class files
    The type java.lang.CharSequence cannot be resolved. It is indirectly referenced from required .class files
    交通测速方式
    卡口和电子警察的区别
    Myeclipse连接Mysql数据库时报错:Error while performing database login with the pro driver:unable
    在window上安装mysql
  • 原文地址:https://www.cnblogs.com/zhangweizhong/p/5075277.html
Copyright © 2011-2022 走看看