我是靠谱客的博主 寒冷导师,这篇文章主要介绍Solr---Facet分面查询,现在分享给大家,希望可以做个参考。

场景描述:

      Solr具有分面查询的功能,其中包含字段分面、间隔分面、区间分面。网上讲的都是字段分面,区间分面少之又少,而且通过solrj从java查询的文章也少的可怜,所以在这里,讲一下我是如何操作的。

设置分面参数:

复制代码
1
2
3
4
5
6
7
// 创建solrQuery对象 SolrQuery query = new SolrQuery(); ... //设置分面 query.setFacet(true); // 设置使用facet query.setFacetMinCount(1); // 设置facet最少的统计数量 query.setFacetLimit(10); // facet结果的返回行数

字段分面:

复制代码
1
2
3
4
5
6
7
8
9
/*字段分面*/ query.addFacetField("FILE_TYPE"); // facet的字段 文档类型 query.addFacetField("DISEASE_TYPE"); // facet的字段 疾病 query.addFacetField("DEPT_NAME"); // facet的字段 科室 query.addFacetField("SEX"); // facet的字段 性别 ... // 执行搜索,返回response对象 QueryResponse rq = cloudSolrClient.query(query);
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*字段分面*/ List<FacetField> flist=rq.getFacetFields(); // 格式为:{分面字段:{字段内容:计数}...},比如{SEX:{"男":17,"女":15},DEPT_NAME:{...}...} JSONObject facetJson = new JSONObject(); // 格式为:{字段内容:计数},比如{"男":17} JSONObject facetContentJson = new JSONObject(); for(FacetField ff : flist) {     // 每次清空之前的内容     facetContentJson.clear();     // 这里采用全名,是为了避免与其他分面的变量名同为Count的问题     for(org.apache.solr.client.solrj.response.FacetField.Count c:ff.getValues()) {         facetContentJson.put(c.getName(), c.getCount());     }     facetJson.accumulate(ff.getName(), facetContentJson );    }

间隔分面:

复制代码
1
2
3
/*间隔分面*/ query.addIntervalFacets("AGE",new String[]{"[0,1]","(1,14]","[15,35]","(35,60]","(60,*]"});
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/* 间隔分面*/ //年龄间隔分面 for (IntervalFacet intervalFacet:rq.getIntervalFacets()){     // 清空之前数据     facetContentJson.clear(); for( IntervalFacet.Count c:intervalFacet.getIntervals()) { //区间分面内容【0-1】,(1,14】,【15,35】,(35,60】,(60,*】 switch (i){ case 0: if (c.getCount()==0){ break; }else{ facetContentJson.put("0-1岁", c.getCount()); break; } case 1: if (c.getCount()==0){ break; }else{ facetContentJson.put("1-14岁", c.getCount()); break; } case 2: if (c.getCount()==0){ break; }else{ facetContentJson.put("15-35岁", c.getCount()); break; } case 3: if (c.getCount()==0){ break; }else{ facetContentJson.put("35-60岁", c.getCount()); break; } case 4: if (c.getCount()==0){ break; }else{ facetContentJson.put("60岁以上", c.getCount()); break; } default: break; } }     facetJson.accumulate(intervalFacet.getField(), facetContentJson); }

时间区间分面:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
/*时间区间分面*/ // 2010-今年 // 时间对象 Calendar cal = Calendar.getInstance(); // 设置当前时间为加8小时,因为时区的问题,在处理之后发送查询条件中是减过8小时的所以这里,加上8小时 cal.add(Calendar.HOUR,+8); // java时间格式 SimpleDateFormat ymdhmsSdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 设置solr时间格式 SimpleDateFormat solrSdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); // 按月分 query.addDateRangeFacet("CREATE_TIME", ymdhmsSdf.parse("2010-01-01 08:00:00"),cal.getTime() , "+1MONTH");
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* 时间区间分面*/ @SuppressWarnings("rawtypes") List<RangeFacet> rlist=rq.getFacetRanges(); if(rlist!=null&&rlist.size()>0){ for(int i=0;i<rlist.size();i++) { List<org.apache.solr.client.solrj.response.RangeFacet.Count> clist=rlist.get(i).getCounts(); // 清空之前数据 facetContentJson.clear(); // 将月份与月份对应的结果放入的分面json中 for(int j=clist.size()-1;j>=0;j--) { facetContentJson.put(ymSdf.format(solrSdf.parse(clist.get(j).getValue())), clist.get(j).getCount()); } facetJson.accumulate(rlist.get(i).getName(), facetContentJson); } }

        该方法(addDateRangeFacet)是针对时间的,其中作为时间区间分面的字段在Solr配置文件中需要设置为时间格式,还有一个方法是针对数字区间的(addNumericRangeFacet)。其中时间区间的方法最后一个参数是时间间隔“gap”为字符串属性,内容为”+1YEAR”,”+1MONTHS”,”+1DAY”,”+1HOUR”。

总结:

    结果的结构里都有Count类型数据,但是字段分面的是FacetField.Count,区间分面的是RangeFacet.Count,所以在遍历Count属性的List时候,我是将整个包名放在上面,如果你只用到两种分面中的一种,则不需要这样写,只导入你用的那个包就够了。其中可以注意到,从Solr里获取到的时间格式为:"yyyy-MM-dd'T'HH:mm:ss'Z'",这个是Solr固定的时间格式。

注意事项:

1.在后续时间处理诸如,query.addFilterQuery(entry.getKey()+":["+solrSdf.format(sdf.parse((String) entry.getValue()))+" TO NOW]");这样的时间处理时,格式需要特别注意,“TO”两边的空格也不能漏掉。“]”代表包含,“}”代表不包含;

2.时间区间的查询时间范围,因为时区的问题,增加了8小时;原因请参考我的这一篇

3.java中的时间格式“YYYY”与“yyyy”是两种概念也需要注意,不能写错了。



最后

以上就是寒冷导师最近收集整理的关于Solr---Facet分面查询的全部内容,更多相关Solr---Facet分面查询内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(59)

评论列表共有 0 条评论

立即
投稿
返回
顶部