[置頂] 電商搜索之動態屬性值(特征值)聚合
來源:程序員人生 發布時間:2016-02-27 15:59:25 閱讀次數:2866次
轉載請標明出處: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"));
}
}
關于 以后的查詢 就不多解釋了。就通過傳遞的業務參數來判斷是不是為 動態屬性值。
版權聲明:本文為博主原創文章,未經博主允許不得轉載。
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈