微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

转载请标明出处: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"));
				
			}
			
		}
关于 之后的查询 就不多解释了。就通过传递的业务参数来判断是否为 动态属性值。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


迭代器模式(Iterator)迭代器模式(Iterator)[Cursor]意图:提供一种方法顺序访问一个聚合对象中的每个元素,而又不想暴露该对象的内部表示。应用:STL标准库迭代器实现、Java集合类型迭代器等模式结构:心得:迭代器模式的目的是在不获知集合对象内部细节的同时能对集合元素进行遍历操作
高性能IO模型浅析服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种:(1)同步阻塞IO(BlockingIO):即传统的IO模型。(2)同步非阻塞IO(Non-blockingIO):默认创建的socket都是阻塞的,非阻塞IO要求socket被设置为NONBLOCK。注意这里所说的N
策略模式(Strategy)策略模式(Strategy)[Policy]意图:定义一系列算法,把他们封装起来,并且使他们可以相互替换,使算法可以独立于使用它的客户而变化。应用:排序的比较方法、封装针对类的不同的算法、消除条件判断、寄存器分配算法等。模式结构:心得:对对象(Context)的处理操作可
访问者模式(Visitor)访问者模式(Visitor)意图:表示一个作用于某对象结构中的各元素的操作,它使你在不改变各元素的类的前提下定义作用于这些元素的新操作。应用:作用于编译器语法树的语义分析算法。模式结构:心得:访问者模式是要解决对对象添加新的操作和功能时候,如何尽可能不修改对象的类的一种方
命令模式(Command)命令模式(Command)[Action/Transaction]意图:将一个请求封装为一个对象,从而可用不同的请求对客户参数化。对请求排队或记录请求日志,以及支持可撤消的操作。应用:用户操作日志、撤销恢复操作。模式结构:心得:命令对象的抽象接口(Command)提供的两个
生成器模式(Builder)生成器模式(Builder)意图:将一个对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示。 应用:编译器词法分析器指导生成抽象语法树、构造迷宫等。模式结构:心得:和工厂模式不同的是,Builder模式需要详细的指导产品的生产。指导者(Director)使用C
设计模式学习心得《设计模式:可复用面向对象软件的基础》一书以更贴近读者思维的角度描述了GOF的23个设计模式。按照书中介绍的每个设计模式的内容,结合网上搜集的资料,我将对设计模式的学习心得总结出来。网络上关于设计模式的资料和文章汗牛充栋,有些文章对设计模式介绍生动形象。但是我相信“一千个读者,一千个
工厂方法模式(Factory Method)工厂方法模式(Factory Method)[Virtual Constructor]意图:定义一个用于创建对象的接口,让子类决定实例化哪一个类,使一个类的实力化延迟到子类。应用:多文档应用管理不同类型的文档。模式结构:心得:面对同一继承体系(Produc
单例模式(Singleton)单例模式(Singleton)意图:保证一个类只有一个实例,并提供一个访问它的全局访问点。应用:Session或者控件的唯一示例等。模式结构:心得:单例模式应该是设计模式中最简单的结构了,它的目的很简单,就是保证自身的实例只有一份。实现这种目的的方式有很多,在Java中
装饰者模式(Decorator)装饰者模式(Decorator)[Wrapper]意图:动态的给一个对象添加一些额外的职责,就增加功能来说,比生成子类更为灵活。应用:给GUI组件添加功能等。模式结构:心得:装饰器(Decorator)和被装饰的对象(ConcreteComponent)拥有统一的接口