Solr之Facet与FacetPivot的使用和区别

1、基本定义理解

Facet是根据field来进行分组统计,可以得出所有指定Field的统计结果,具体有哪些参数配置,参考:https://blog.csdn.net/weixin_43231076/article/details/102685185
FacetPivot与Facet的功能很相似,但是它可以指定多个field,也就是多个维度来分组统计,并且统计出来的结果可以整理成Tree的结构

2、代码实战举例
2-1、定义实体类:
import org.apache.solr.client.solrj.beans.Field;

public class Product implements Serializable{

	private static final long serialVersionUID = 7300743141456692472L;

	@Field
	private String id;
	@Field
	private String title_s;
	@Field
	private String major_s;
	@Field
	private String subMajor_s;
	@Field
	private String brand_s;
	@Field
	private String model_s;
	@Field
	private int price_i;
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getMajor_s() {
		return major_s;
	}
	public void setMajor_s(String major_s) {
		this.major_s = major_s;
	}
	public String getSubMajor_s() {
		return subMajor_s;
	}
	public void setSubMajor_s(String subMajor_s) {
		this.subMajor_s = subMajor_s;
	}
	public String getBrand_s() {
		return brand_s;
	}
	public void setBrand_s(String brand_s) {
		this.brand_s = brand_s;
	}
	public String getModel_s() {
		return model_s;
	}
	public void setModel_s(String model_s) {
		this.model_s = model_s;
	}
	public int getPrice_i() {
		return price_i;
	}
	public void setPrice_i(int price_i) {
		this.price_i = price_i;
	}
	public String getTitle_s() {
		return title_s;
	}
	public void setTitle_s(String title_s) {
		this.title_s = title_s;
	}
}
2-2、插入测试数据
private static void addIndex() throws Exception{
		HttpSolrClient client = SolrServer.getSolrClient();
		List<Product> list = new ArrayList<>();
		
		Product product1 = new Product();
		product1.setId("1001");
		product1.setTitle_s("SAST/先科 32英寸液晶空调");
		product1.setMajor_s("家用电器");
		product1.setSubMajor_s("空调");
		product1.setBrand_s("先科");
		product1.setModel_s("SAST");
		product1.setPrice_i(6500);
		list.add(product1);
		
		Product product2 = new Product();
		product2.setId("1002");
		product2.setTitle_s("创维55M1 55英寸4K高清洗衣机");
		product2.setMajor_s("家用电器");
		product2.setSubMajor_s("洗衣机");
		product2.setBrand_s("创维");
		product2.setModel_s("55M1");
		product2.setPrice_i(2999);
		list.add(product2);
		
		Product product3 = new Product();
		product3.setId("1003");
		product3.setTitle_s("Hisense/海信HZ55E3D-PRO 空调");
		product3.setMajor_s("家用电器");
		product3.setSubMajor_s("电视");
		product3.setBrand_s("海信");
		product3.setModel_s("HZ55E3D-PRO");
		product3.setPrice_i(5642);
		list.add(product3);
		
		Product product4 = new Product();
		product4.setId("1004");
		product4.setTitle_s("创维5T 65英寸4K全面屏电视机智能网络wifi平板液晶屏家用彩电 55");
		product4.setMajor_s("家用电器");
		product4.setSubMajor_s("电视");
		product4.setBrand_s("创维");
		product4.setModel_s("创维5T");
		product4.setPrice_i(9999);
		list.add(product4);
		
		Product product5 = new Product();
		product5.setId("1005");
		product5.setTitle_s("Changhong/长虹 65A4U 65英寸电视机4K智能网络平板液晶屏LED彩电");
		product5.setMajor_s("家用电器");
		product5.setSubMajor_s("电视");
		product5.setBrand_s("长虹");
		product5.setModel_s("65A4U");
		product5.setPrice_i(1999);
		list.add(product5);
		
		client.addBeans(list);
		client.commit();
		System.out.println("插入数据成功...");
	}
	public static void main(String[] args) throws Exception{
		addIndex();
	}

2-3、测试数据插入成功后,solr查询结果如下:
在这里插入图片描述
2-4、Facet功能测试

public static void queryFacet() throws Exception{
		HttpSolrClient client = SolrServer.getSolrClient();
		SolrQuery sQuery = new SolrQuery();
		
		String para = "*:*";			//查询全部数据
		sQuery.setFacet(true);			//打开Facet查询开关
		sQuery.addFacetField(new String[] {"subMajor_s", "brand_s"});		//添加要进行facet操作
		sQuery.setFacetLimit(100);		//限制Facet的返回数量
		sQuery.setFacetMissing(false);	//false:表示不统计null的值
		sQuery.setFacetMinCount(1);		//分组的最小数据为1
		sQuery.addFacetQuery("price_i:[3000 TO 10000]");		//增加facet的查询条件
		sQuery.setQuery(para);
		
		QueryResponse queryResponse;
		queryResponse = client.query(sQuery);
		List<FacetField> facets = queryResponse.getFacetFields();// 返回的facet列表
		if(facets != null && facets.size() > 0) {
			for(FacetField facet : facets) {
				System.out.println(facet.getName() + "====" + facet.getGap() + "====" + facet.getValueCount());
				System.out.println("------------------");
				
				List<Count> counts = facet.getValues();
				for(int i=0; i<counts.size(); i++) {
					Count count = counts.get(i);
					System.out.println(count.getName() + "====" + count.getCount() + "====" + count.getAsFilterQuery());
					System.out.println();
				}
			}
		}
	}

运行结果:

subMajor_s====null====3
------------------
电视====3====subMajor_s:电视
洗衣机====1====subMajor_s:洗衣机
空调====1====subMajor_s:空调

brand_s====null====4
------------------
创维====2====brand_s:创维
先科====1====brand_s:先科
海信====1====brand_s:海信

由这个结果可以看出,统计结果是根据subMajor_s和brand_s两个Field分组进行统计数量
2-5、FacetPivot测试

private static void queryFacetPivot() throws Exception{
		HttpSolrClient client = SolrServer.getSolrClient();
		SolrQuery sQuery = new SolrQuery();
		String para = "*:*";
		sQuery.setFacet(true);			//打开Facet功能
		sQuery.add("facet.pivot", "major_s,subMajor_s,brand_s");	//添加FacetPivot Field,使用三个维度来分组查询,多个field之间用逗号隔开,注意中间不能使用空格
		sQuery.setFacetLimit(1000);		//限制Facet的返回数量
		sQuery.setQuery(para);
		
		//查询数据,并且设置请求方式为POST,因为如果sQuest的参数过长的话,使用GET请求会出现参数过长的情况
		QueryResponse queryResponse = client.query(sQuery, SolrRequest.METHOD.POST);		
		
		/**
		 * NamedList,一个有序的name/value容器,NamedList不像Map,他具有以下特点:
      			1、名字可以重复
      			2、NamedList中的element保持这有序状态
      			3、可以下标的形式访问Elements
      			4、name和value都可以为null

		 */
		NamedList<List<PivotField>> namedList = queryResponse.getFacetPivot();
		System.out.println(namedList);
		if(namedList != null) {
			for(int i=0; i<namedList.size(); i++) {
				List<PivotField> pivotList = namedList.getVal(i);
				if(pivotList != null) {
					for(PivotField privoField : pivotList) {
						System.out.println("一级====" + privoField.getValue() + "====" + privoField.getCount());
						List<PivotField> fieldList = privoField.getPivot();
						if(fieldList != null) {
							for(PivotField item : fieldList) {
								System.out.println("二级====" + item.getValue() + "====" + item.getCount());
								List<PivotField> fieldList1 = item.getPivot();
								if(fieldList1 != null) {
									for(PivotField item1 : fieldList1) {
										System.out.println("三级====" + item1.getValue() + "====" + item1.getCount());
									}
							}
							}
						}
					}
				}
			}
		}
	}

运行结果:

{major_s,subMajor_s,brand_s=[major_s:家用电器 [5] [subMajor_s:电视 [3] [brand_s:创维 [1] null, brand_s:海信 [1] null, brand_s:长虹 [1] null], subMajor_s:洗衣机 [1] [brand_s:创维 [1] null], subMajor_s:空调 [1] [brand_s:先科 [1] null]]]}
一级====家用电器====5
二级====电视====3
三级====创维====1
三级====海信====1
三级====长虹====1
二级====洗衣机====1
三级====创维====1
二级====空调====1
三级====先科====1

由此结果可看出:
FacetPivot不仅可以为每一个Field统计数量,并且可以将统计的结果整理成Tree型结构

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章