最近在做一个项目,对应用进行搜索且要支持分类查询;
这个功能在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界面实验下在页面上查询返回的数据是怎么样的!
这里我们设置q 的值为name:*天天惠*,勾选facet选项,在facet.field设置分面字段。点击查询。
可以看到返回结果中的facet_fields中的artist,对artist进行了统计。
通过SolrJ API进行查询结果返回QueryResponse对象,获取对象中每个面的统计结果使用getFacetField方法。
FacetField facetField = rsp.getFacetField("artist");//rsp为QueryResponse对象实例
最终实现结果如下图: