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

前端之家收集整理的这篇文章主要介绍了电商搜索之动态属性值(特征值)聚合前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

转载请标明出处:http://www.jb51.cc/article/p-uyrrhjxl-bam.html

在一些电商网站中,有部分这样的搜索需求:

1:根据关键字搜索商品,要制作商品属性值(也称特征值,导航栏),但是这个商品属性值(也称特征值,导航栏)是动态的。

2:关键字是和台式机有关的,那么属性值要有cpu型号,显卡型号等等参数选择。

3:关键字是和服装相关的,那么属性值要有款式,尺码,等等参数选择。

4:有些公共的属性,比如品牌、价位、类别、大家说。

类似京东:



在solr中,用facet 可以实现以上属性值聚合的需求,facet的基本功能就是对搜索结果中的商品的共有属性进行聚合统计。facet功能很强大,具体本文就不相信列出了。

但是非公共属性值的话,solr要求facet 必须要指定聚合字段,没有字段是完不了facet操作的。

如何完成以上需求?

当初一共思考了两种方案:


一:这一种方案可行性挺高,由于我没有采用该方案,但是这种方式我认为 是可以实现的。

把所有的商品的动态(非共性)的属性值建立索引的时候,全部以特殊符号形成的格式加入某个指定字段,如:key:value,key:value......用这个数据格式去存储商品的

所有属性值。 然后用自定义的分词器(通过“:” “,” 的切词规则)切开这些属性值,然后在进行该字段的facet聚合。

二:在我的实际应用中,我采用的是这种方案,具体实现:

在solr中,有一种字段是动态的,dynamicField。指定所有非公共属性特征值字段存储格式为:

<dynamicField name="*_proper" type="string" indexed="true" stored="true"/><!-- 动态string字段 -->

注:用于facet的字段的索引index一定要设为true,不要分词,默认使用string类型。


这样还有那个问题,我们还是不知道具体应该facet的字段是哪一个。

那么,分两次查询

第一次查询所有非公共属性名称(key)。

<field name="proper" type="string" indexed="true" stored="true"  multiValued="true"/> 

用这一个在第一次查询的时候就可以确定,返回结果中有哪些属性值字段应该被facet聚合。


第二次查询就可以指定以上字段:key_proper 字段作为facet字段。

附上业务代码

		/**
		 * 特征值聚合
		 * 先获取结果集文档中的特征属性
		 * 对特征属性进行二次聚合  域:  属性+_string 进行第二次查询
		 * 处理结果
		 */
		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());
				}
			}
			//进行第二次查询
			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"));
				
			}
			
		}
关于 之后的查询 就不多解释了。就通过传递的业务参数来判断是否为 动态属性值。 原文链接:https://www.f2er.com/javaschema/284379.html

猜你在找的设计模式相关文章