国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > php开源 > 综合技术 > [置顶] 电商搜索之动态属性值(特征值)聚合

[置顶] 电商搜索之动态属性值(特征值)聚合

来源:程序员人生   发布时间:2016-02-27 15:59:25 阅读次数:2566次

转载请标明出处: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")); } }

关于 以后的查询 就不多解释了。就通过传递的业务参数来判断是不是为 动态属性值。

版权声明:本文为博主原创文章,未经博主允许不得转载。

生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生