转载请标明出处:http://blog.csdn.net/hu948162999/article/details/49280071
在1些电商网站中,有部份这样的搜索需求:
1:根据关键字搜索商品,要制作商品属性值(也称特点值,导航栏),但是这个商品属性值(也称特点值,导航栏)是动态的。
2:关键字是和台式机有关的,那末属性值要有CPU型号,显卡型号等等参数选择。
3:关键字是和服装相干的,那末属性值要有款式,尺码,等等参数选择。
4:有些公共的属性,比如品牌、价位、种别、大家说。
类似京东:
在solr中,用facet 可以实现以上属性值聚合的需求,facet的基本功能就是对搜索结果中的商品的共有属性进行聚合统计。facet功能很强大,具体本文就不相信列出了。
但是非公共属性值的话,solr要求facet 必须要指定聚合字段,没有字段是完不了facet操作的。
如何完成以上需求?
当初1共思考了两种方案:
1:这1种方案可行性挺高,由于我没有采取该方案,但是这类方式我认为 是可以实现的。
把所有的商品的动态(非共性)的属性值建立索引的时候,全部以特殊符号构成的格式加入某个指定字段,如:key:value,key:value......用这个数据格式去存储商品的
所有属性值。 然后用自定义的分词器(通过“:” “,” 的切词规则)切开这些属性值,然后在进行该字段的facet聚合。
2:在我的实际利用中,我采取的是这类方案,具体实现:
在solr中,有1种字段是动态的,dynamicField。指定所有非公共属性特点值字段存储格式为:
<dynamicField name="*_proper" type="string" indexed="true" stored="true"/><!-- 动态string字段 -->
注:用于facet的字段的索引index1定要设为true,不要分词,默许使用string类型。
这样还有那个问题,我们还是不知道具体应当facet的字段是哪个。
那末,分两次查询。
第1次查询所有非公共属性名称(key)。
<field name="proper" type="string" indexed="true" stored="true" multiValued="true"/>
用这1个在第1次查询的时候就能够肯定,返回结果中有哪些属性值字段应当被facet聚合。
第2次查询就能够指定以上字段:key_proper 字段作为facet字段。
附上业务代码:
/**
* 特点值聚合
* 先获得结果集文档中的特点属性
* 对特点属性进行2次聚合 域: 属性+_string 进行第2次查询
* 处理结果
*/
FacetField properField = response.getFacetField("proper");
List<Count> propercounts =properField.getValues();
if (propercounts != null) {
//所有特点值属性
List<String> propers=new ArrayList();
for (Count count : propercounts) {
if (count.getCount() != 0) {
propers.add(count.getName());
}
}
//进行第2次查询
if(propers.size()>0){
SolrQuery query=new SolrQuery();
if(!isEmpty(map1, "keyword")){
query.setParam("q", map1.get("keyword").toString());
}else{
query.setParam("q", "*");
}
for(String proper:propers){
query.addFacetField(proper+"_proper");
}
QueryResponse properRresponse = server.query(query);
List properlist=new ArrayList();
Map propermap =new HashMap();
for(String proper:propers){
FacetField dynamicProperField = properRresponse.getFacetField(proper+"_proper");
List dynamicProperFieldList=new ArrayList();//返回结果集
List<Count> dynamicPropercounts =dynamicProperField.getValues();
if (dynamicPropercounts != null) {
for (Count count : dynamicPropercounts) {
if (count.getCount() != 0) {
dynamicProperFieldList.add(count.getName()) ;
}
}
propermap.put(proper, dynamicProperFieldList);
// System.out.println(proper+":"+propermap.get(proper));
}
}
properlist.add(propermap);
returnMap.put("proper", properlist);
// System.out.println(returnMap.get("proper"));
}
}
关于 以后的查询 就不多解释了。就通过传递的业务参数来判断是不是为 动态属性值。
版权声明:本文为博主原创文章,未经博主允许不得转载。