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. 普通分组,按照某个字段分组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 </span>=<span style="color:#000000;"> facet;

        </span><span style="color:#008000;">//</span><span style="color:#008000;">条件集合之间的关系</span>
        <span style="color:#0000ff;">var</span> qTBO = <span style="color:#0000ff;">new</span> SolrMultipleCriteriaQuery(query, <span style="color:#800000;">"</span><span style="color:#800000;">AND</span><span style="color:#800000;">"</span><span style="color:#000000;">);

        SolrQueryResults</span>&lt;Product&gt; results =<span style="color:#000000;"> solr.Query(qTBO, options);

        DateFacetingResult dateFacetResult </span>= results.FacetDates[<span style="color:#800000;">"</span><span style="color:#800000;">updatetime</span><span style="color:#800000;">"</span><span style="color:#000000;">];

        </span><span style="color:#0000ff;">foreach</span> (KeyValuePair&lt;DateTime, <span style="color:#0000ff;">int</span>&gt; dr <span style="color:#0000ff;">in</span><span style="color:#000000;"> dateFacetResult.DateResults)
        {
            Console.WriteLine(dr.Key);
            Console.WriteLine(dr.Value);
        }</span>
 

 

      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);

        </span><span style="color:#0000ff;">var</span> facet = <span style="color:#0000ff;">new</span><span style="color:#000000;"> FacetParameters
         {
             Queries </span>= <span style="color:#0000ff;">new</span>[] { <span style="color:#0000ff;">new</span> SolrFacetQuery(lessThan30), <span style="color:#0000ff;">new</span> SolrFacetQuery(lessThan70), <span style="color:#0000ff;">new</span><span style="color:#000000;"> SolrFacetQuery(moreThan70) }
         };

        options.Facet </span>=<span style="color:#000000;"> facet;

        </span><span style="color:#0000ff;">var</span> qTBO = <span style="color:#0000ff;">new</span> SolrMultipleCriteriaQuery(query, <span style="color:#800000;">"</span><span style="color:#800000;">AND</span><span style="color:#800000;">"</span><span style="color:#000000;">);

        SolrQueryResults</span>&lt;Product&gt; results =<span style="color:#000000;"> solr.Query(qTBO, options);
        </span><span style="color:#0000ff;">foreach</span> (<span style="color:#0000ff;">var</span> f <span style="color:#0000ff;">in</span><span style="color:#000000;"> results.FacetQueries)
        {
            Console.WriteLine(</span><span style="color:#800000;">"</span><span style="color:#800000;">{0}: {1}</span><span style="color:#800000;">"</span><span style="color:#000000;">, f.Key, f.Value);
        }</span>
 

      

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

 
    <span style="color:#808080;">///</span> <span style="color:#808080;">&lt;summary&gt;</span>
    <span style="color:#808080;">///</span><span style="color:#008000;"> Facet 查询
    </span><span style="color:#808080;">///</span> <span style="color:#808080;">&lt;/summary&gt;</span>
    <span style="color:#808080;">///</span> <span style="color:#808080;">&lt;param name="color"&gt;&lt;/param&gt;</span>
    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">void</span><span style="color:#000000;"> Query_FactPivot()
    {
        ISolrOperations</span>&lt;Product&gt; solr = ServiceLocator.Current.GetInstance&lt;ISolrOperations&lt;Product&gt;&gt;<span style="color:#000000;">();
        </span><span style="color:#008000;">//</span><span style="color:#008000;">Create a facet Pivot Query</span>
        <span style="color:#0000ff;">var</span> facetPivotQuery = <span style="color:#0000ff;">new</span><span style="color:#000000;"> SolrFacetPivotQuery()
        {
            </span><span style="color:#008000;">//</span><span style="color:#008000;">默认是 1 pivot, 先 category 再按 color 分组
            </span><span style="color:#008000;">//</span><span style="color:#008000;">如果是多个,则在后面继续追加 ,new PivotFields("color", "category")</span>
            Fields = <span style="color:#0000ff;">new</span>[] { <span style="color:#0000ff;">new</span> PivotFields(<span style="color:#800000;">"</span><span style="color:#800000;">color</span><span style="color:#800000;">"</span>, <span style="color:#800000;">"</span><span style="color:#800000;">category</span><span style="color:#800000;">"</span><span style="color:#000000;">)},

            </span><span style="color:#008000;">//</span><span style="color:#008000;">最小记录数</span>
            MinCount = <span style="color:#800080;">1</span><span style="color:#000000;">
        };

        </span><span style="color:#008000;">//</span><span style="color:#008000;">创建一个查询参数
        </span><span style="color:#008000;">//</span><span style="color:#008000;">同时 pivotQueries 可以和其他查询条件一起混用</span>
        <span style="color:#0000ff;">var</span> facetParams = <span style="color:#0000ff;">new</span><span style="color:#000000;"> FacetParameters()
        {
            Queries </span>= <span style="color:#0000ff;">new</span><span style="color:#000000;">[] { facetPivotQuery },

            Limit </span>= <span style="color:#800080;">15</span><span style="color:#000000;">
        };

        </span><span style="color:#0000ff;">var</span> queryOptions = <span style="color:#0000ff;">new</span><span style="color:#000000;"> QueryOptions();
        queryOptions.Facet </span>=<span style="color:#000000;"> facetParams;
        queryOptions.Rows </span>= <span style="color:#800080;">0</span><span style="color:#000000;">;

        </span><span style="color:#0000ff;">var</span> results = solr.Query(<span style="color:#800000;">"</span><span style="color:#800000;">*:*</span><span style="color:#800000;">"</span><span style="color:#000000;">, queryOptions);
        </span><span style="color:#0000ff;">if</span> (results.FacetPivots.Count &gt; <span style="color:#800080;">0</span><span style="color:#000000;">)
        {
            </span><span style="color:#0000ff;">foreach</span> (<span style="color:#0000ff;">var</span> pivotTable <span style="color:#0000ff;">in</span><span style="color:#000000;"> results.FacetPivots)
            {
                Console. WriteLine(</span><span style="color:#800000;">"</span><span style="color:#800000;">Pivot table for </span><span style="color:#800000;">"</span> +<span style="color:#000000;"> pivotTable.Key);
                </span><span style="color:#0000ff;">foreach</span> (<span style="color:#0000ff;">var</span> pivot <span style="color:#0000ff;">in</span><span style="color:#000000;"> pivotTable.Value)
                {
                    Console.WriteLine(</span><span style="color:#800000;">"</span><span style="color:#800000;">  Pivot: </span><span style="color:#800000;">"</span> + pivot.Field + <span style="color:#800000;">"</span><span style="color:#800000;"> with value </span><span style="color:#800000;">"</span> + pivot.Value + <span style="color:#800000;">"</span><span style="color:#800000;">. Child Pivots:</span><span style="color:#800000;">"</span><span style="color:#000000;">);
                    </span><span style="color:#0000ff;">foreach</span> (<span style="color:#0000ff;">var</span> pivotChild <span style="color:#0000ff;">in</span><span style="color:#000000;"> pivot.ChildPivots)
                    {
                        Console.WriteLine(</span><span style="color:#800000;">"</span><span style="color:#800000;">    - </span><span style="color:#800000;">"</span> + pivotChild.Value + <span style="color:#800000;">"</span><span style="color:#800000;"> (</span><span style="color:#800000;">"</span> + pivotChild.Count + <span style="color:#800000;">"</span><span style="color:#800000;">)</span><span style="color:#800000;">"</span><span style="color:#000000;">);
                    }
                }
            }
        }

        Console.ReadKey();
    }      </span>
 

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

posted @ 2016-08-10 16:31  ProgramerCat  阅读(75)  评论(0编辑  收藏  举报