solr搜索服务 Facet,FacetPivot,Group

1,Facet介绍

  Facet是solr的高级搜索功能之一,可以给用提供更友好的搜索体验,在搜索关键字的同时,能够按照Facet的字段进行分组并统计。

  facet分类:

  普通facet,比如从厂商品牌的维度建立fact.

  查询facet,比如根据价格查询时,将根据价格,设置多个区间,比如0-10,10-20,20-30等。

  日期facet,也是一种特殊的范围查询,比如按照月份进行facet

2,Facet查询

  进行Facet查询需要在请求参数中加入 “facet=on” 或 “facet=true” 只有这样facet组件才起作用

    Filed Facet

    Facet字段通过在请求中加入“facet.field”参数加以声明,如果需要对多个字段进行facet查询,那么将该参数声明多次,比如:

    http://localhost:8081/solr/select?q=联想&facet=on&facet.field=cpu&facet.field=videoCard

    各个Facet字段互不影响,且可以针对每个Facet字段设置查询参数。一下介绍的参数既可以应用于所有的facet字段,也可以应用与每个单独facet字段。应用于单独的字段时通过f.字段名.参数名=参数值,这种方式调用。比如facet.prefix参数应用于cpu字段,可以采用如下形式f.cpu.facet.prefix=Intel

   示例代码:

    sQuery.setFacet(true);//设置facet=on
    sQuery.addFacetField(new String[] { "subMajor_s","brand_s" });//设置需要facet的字段
    sQuery.setFacetLimit(1000);//-1 // 限制facet返回的数量
    sQuery.setFacetMissing(false);// 不统计null的值
    sQuery.setFacetMinCount(1);// 设置返回的数据中每个分组的数据最小值,比如设置为1,则统计数量最小为1,不然不显示
    sQuery.addFacetQuery("price_i:[1000 TO 10000]");
    sQuery.setQuery(para);
    QueryResponse queryResponse;
    queryResponse = solrServer.query(sQuery);
    List<FacetField> facets = queryResponse.getFacetFields();// 返回的facet列表

    for (FacetField facet :facets) {
      System.out.println(facet.getName());
      System.out.println("----------------");
      List<Count>counts = facet.getValues();
      for (Count count : counts){
        System.out.println(count.getName()+":"+ count.getCount());
      }
      System.out.println();
    }

3,什么是Facet.pivot

  Facet.pivot就是按照多个维度进行分组查询,是facet的加强,在实际运用中经常用到,一个典型的例子就是商品目录树

  

  示例代码:

    HttpSolrClient solrServer = SolrServer.getServer();
    SolrQuery sQuery = new SolrQuery();
    sQuery.setFacet(true);
    sQuery.add("facet.pivot", "major_s, subMajor_s");//两维度来分组查询
    sQuery.setFacetLimit(1000);
    sQuery.setQuery(para);
    QueryResponse response = solrServer.query(sQuery,SolrRequest.METHOD.POST);
    NamedList<List<PivotField>> namedList = response.getFacetPivot();
    NamedList解释:
    NamedList,一个有序的name/value容器,NamedList不像Map,他具有以下特点:
      1、名字可以重复
      2、NamedList中的element保持这有序状态
      3、可以下标的形式访问Elements
      4、name和value都可以为null

    List<PivotField> pivotList = null;
    for(int i=0;i<namedList.size();i++){ //此处的多次循环可以用递归
    pivotList = namedList.getVal(i);
    if(pivotList != null){
      for(PivotField pivot:pivotList){
      System.out.println("一级 : "+pivot.getValue() + " " + pivot.getCount());
      List<PivotField> fieldList = pivot.getPivot();
      if(fieldList != null){
        for(PivotField field:fieldList){
          System.out.println("二级 : "+field.getValue() + " " + field.getCount());
          List<PivotField> fieldList1 = field.getPivot();
          if(fieldList1 != null){
            for(PivotField field1:fieldList1){
              System.out.println("三级 : "+field1.getValue() + " " + field1.getCount());

            }
          }
        }
      }
      }
    }
    }

 4,Group于Facet的区别

  facet的查询结果主要是分组信息:有什么分组,每个分组包括多少记录;但是分组中有那些数据是不可知道的,只有进一步搜索。

  group则类似于关系型数据库中的group by,可以用于一个或者几个字段去重,显示一个group的前几条记录等。 

  HttpSolrClient solrServer = SolrServer.getServer();
  SolrQuery query = new SolrQuery("brand_s:海尔");//"subMajor_s:空调" "*:*"
  // 设置通过Group查询为true,表示查询时使用Group机制
  query.setParam(GroupParams.GROUP, true);
  // 设置Group查询针对的域
  query.setParam(GroupParams.GROUP_FIELD, "brand_s");
  // 设置每个组最多返回的记录数,可用于数据采集;若只需要数量,可以设置为0
  query.setParam(GroupParams.GROUP_LIMIT, "5");
  // 设置返回的行数
  query.setRows(10);
  // 获取查询响应
  QueryResponse response = solrServer.query(query);
  if (response != null) {// 获取group查询响应
    GroupResponse groupResponse = response.getGroupResponse();   

    if (groupResponse != null) {
      List<GroupCommand> groupList = groupResponse.getValues();
      for (GroupCommand groupCommand : groupList) {
        List<Group> groups = groupCommand.getValues();
        for (Group group : groups) {
          System.out.println(group.getResult().get(0).getFirstValue("subMajor_s")
+" "+ group.getResult().get(1).getFirstValue("subMajor_s"));
          System.out.println("group查询..." + group.getGroupValue() + " 数量为:" + group.getResult().getNumFound() + " " + group.getResult().get(0).getFieldValue("model_s"));
        }
      }
    }
  }
  访问地址:http://localhost:8081/solr/test/select?q=brand_s:xx&group=true&group.field=brand_s&group.limit=5&rows=10

  访问地址:http://localhost:8081/solr/test/select?q=brand_s:xx&facet=true&facet.field=brand_s&facet.limit=10&facet.missing=false&facet.mincount=1

 

  

posted @ 2020-09-27 10:32  漫步程序路  阅读(498)  评论(0)    收藏  举报