[置顶] 【Apache Solr系列之五】使用Solr客户端SolrJ实现多层面统计

最近在做一个项目,对应用进行搜索且要支持分类查询;

这个功能在solr上实现其实蛮简单的。使用solr的fecet功能即可轻松实现。

我们先看下样例数据:

{
        "id": 310683,
        "name": "A Blobber Popper",
        "type_name": "家庭游戏",
        "app_updated_time": "2013-10-16T16:00:00Z",
        "id_in_data": 718985737,
        "artist_id": 628,
        "artist": "Timo Lehtikevari",
        "type_id": 33,
        "img_hit": "http://a1227.phobos.apple.com/us/r30/Purple4/v4/45/93/47/4593474d-9d07-f59b-01e2-8788bee510eb/mzl.llswugwf.75x75-65.png",
        "is_free": true,
        "_version_": 1453475483495694300
      }
这里有几个字段要做下说明

artist_id:商家ID

type_id:类型ID

is_free:是否免费

我们要根据关键字查询对应的应用,还要实现围绕以上这三个数据层面进行统计。


那么需求确定了,接下来我们来实现我们所想要的功能。这里客户端框架使用SolrJ来实现。

/**
	 * 查询总入口
	 * 
	 * @param fields
	 *            查询字段
	 * @param values
	 *            查询key值 field:key
	 * @param start
	 *            起始位置
	 * @param count
	 *            读取总数
	 * @param sortfields
	 *            排序字段
	 * @param flags
	 *            排序标志
	 * @param fecteField 分面统计字段
	 * @return QueryResponse
	 * @author:Jonathan.Wei
	 * @date:2013-11-27
	 */
	public static QueryResponse search(String[] fields, String[] values,
			String[] fqs, String[] fqValues, int start, int count,
			String[] sortfields, Boolean[] flags,String[]fecteField) {
		init();
		// 检测输入是否合法
		if (null == fields || null == values || fields.length != values.length) {
			return null;
		}
		if (null == sortfields || null == flags
				|| sortfields.length != flags.length) {
			return null;
		}
		SolrQuery query = null;
		try {
			// 初始化查询对象
			query = new SolrQuery();
			query.setQuery(fields[0] + ":" + values[0]);
			// 设置起始位置与返回结果数
			if (start!=0) {
				query.setStart(start);
			}
			if (count!=0) {
				query.setRows(count);
			}
			if (null!=fecteField) {
				query.setFacet(true);
				query.setFacetLimit(20);
				query.setFacetMinCount(1);
				query.addFacetField(fecteField);
			}
			boolean isFq = false;
			if (fqs != null && fqs.length > 0) {
				if (fqs.length == fqValues.length) {
					isFq = true;
				}
			}
			if (isFq) {
				for (int i = 0; i < flags.length; i++) {
					String fq = fqs[i] + ":" + fqValues[i];
					query.setFilterQueries(fq);
				}
			}
			// 设置排序
			for (int i = 0; i < sortfields.length; i++) {
				if (flags[i]) {
					query.addSortField(sortfields[i], SolrQuery.ORDER.asc);
				} else {
					query.addSortField(sortfields[i], SolrQuery.ORDER.desc);
				}
			}
		} catch (Exception e) {
			LOG.error(e.getMessage());
		}

		QueryResponse rsp = null;
		try {
			rsp = solrServer.query(query);
		} catch (Exception e) {
			LOG.error(e.getMessage());
			return null;
		}
		// 返回查询结果
		return rsp;
	}
以上是我的一个solrj的帮助方法。因为我们无需使用到太复杂的查询,所以这个方法只能满足我们当前需求,对于复杂的需求还是要对这个方法重新进行修改的。

我们先到solr的web界面实验下在页面上查询返回的数据是怎么样的!

[置顶] 【Apache Solr系列之五】使用Solr客户端SolrJ实现多层面统计_第1张图片

这里我们设置q 的值为name:*天天惠*,勾选facet选项,在facet.field设置分面字段。点击查询。

可以看到返回结果中的facet_fields中的artist,对artist进行了统计。


通过SolrJ API进行查询结果返回QueryResponse对象,获取对象中每个面的统计结果使用getFacetField方法。

FacetField facetField = rsp.getFacetField("artist");//rsp为QueryResponse对象实例

注:我们刚才在界面中查询中只填了一个facet.field字段。因为在界面上好像是不支持输入多个field的。但是我们可以通过SolrJ API进行调用,设置多个field,这样就会返回多个fecet的统计结果。


最终实现结果如下图:

[置顶] 【Apache Solr系列之五】使用Solr客户端SolrJ实现多层面统计_第2张图片


你可能感兴趣的:(Solr,solrj,分面统计)