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

浙公网安备 33010602011771号