最近在做一个项目,对应用进行搜索且要支持分类查询;
这个功能在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对象实例
注:我们刚才在界面中查询中只填了一个facet.field字段。因为在界面上好像是不支持输入多个field的。但是我们可以通过SolrJ API进行调用,设置多个field,这样就会返回多个fecet的统计结果。
最终实现结果如下图: