Solr6.0通过Solrj进行字段分面及区间分面,并获取分面结果

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

设置查询条件:

//设置分面
query.setFacet(true); // 设置使用facet
query.setFacetMinCount(1); // 设置facet最少的统计数量
query.setFacetLimit(10); // facet结果的返回行数
query.addFacetField("FILE_TYPE"); // facet的字段 文档类型
query.addFacetField("DISEASE_TYPE"); // facet的字段 疾病
query.addFacetField("DEPT_NAME"); // facet的字段 科室
query.addFacetField("SEX"); // facet的字段 性别
//query.addFacetField("DIAG_NAME"); // facet的字段 疑似诊断
// 设置solr时间格式
SimpleDateFormat solrSdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
// 年份的java时间格式
SimpleDateFormat sdf=new SimpleDateFormat("yyyy");
query.addDateRangeFacet("REG_TIME", sdf.parse("2010"),sdf.parse(sdf.format(new Date())) , "+1YEAR"); //区间分面 2010-今

    上面这个方法在源码中可以找到,该方法是针对时间的,其中作为时间区间分面的字段在Solr中需要设置为时间格式,还有一个方法是针对数字区间的(addNumericRangeFacet)。其中时间区间的方法最后一个参数是时间间隔“gap”为字符串属性,内容为”+1YEAR”,”+1MONTHS”,”+1DAY”,”+1HOUR”。接下来是获取查询出的分面结果。查询出来的结果是类似2010-2011,2011-2012...这样的统计,我这里是需要2010年-今,2011年-今的统计,所以在分面结果做进一步处理,当然也可是使用查询分面功能,给每一个条件添加范围,但是我觉得会增大solr查询条件给solr压力,或者java中代码量会变多,所以使用了区间分面。

获取查询结果:

		// 分面结果,内容为所有分面的集合
		// 字段分面
		List<FacetField> flist=rq.getFacetFields();
		for(FacetField ff : flist) {
			// 字段名
			System.out.println("field:"+ff.getName());
			for(org.apache.solr.client.solrj.response.FacetField.Count c:ff.getValues()) {
				// 内容名
				System.out.println("name:"+c.getName());
				// 统计数
				System.out.println("count:"+c.getCount());
			}
		}
		// 区间分面
		@SuppressWarnings("rawtypes")
		List<RangeFacet> rlist=rq.getFacetRanges();
		for(int i=0;i<rlist.size();i++) {
			@SuppressWarnings("unchecked")
			List<org.apache.solr.client.solrj.response.RangeFacet.Count> clist=rlist.get(i).getCounts();
			// 年份的数量统计,方便在之上叠加
			int yearCount=0;
			// 年份越小,至今的文档越多,所以采用从今到过去的遍历,也就是倒序
			for(int j=clist.size()-1;j>=0;j--) {
				yearCount+=clist.get(j).getCount();
				// 哪一年以来
				// 因为solr返回结果是以上一年最后一天为计时(不包括那一天),所以年份+1
				System.out.println(Integer.parseInt(sdf.format(solrSdf.parse(clist.get(j).getValue())))+1+"年以来");
				// 统计数
				System.out.println("yearCount:"+yearCount);
			}
		}


    从上面代码可以看出,获取分面结果的是两种方法,结果的结构里都有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]");这样的时间处理时,格式需要特别注意,而且字符串里面的空格也不能漏掉。

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

猜你喜欢

转载自blog.csdn.net/henrymrz/article/details/79563351