...
|
...
|
@@ -3,7 +3,6 @@ package com.yoho.search.service.scene.shopbrand; |
|
|
import com.alibaba.fastjson.JSONArray;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.yoho.error.event.SearchEvent;
|
|
|
import com.yoho.search.aop.cache.SearchCacheAble;
|
|
|
import com.yoho.search.base.utils.EventReportEnum;
|
|
|
import com.yoho.search.base.utils.ISearchConstants;
|
|
|
import com.yoho.search.base.utils.ProductIndexEsField;
|
...
|
...
|
@@ -24,7 +23,6 @@ import org.elasticsearch.search.aggregations.Aggregation; |
|
|
import org.elasticsearch.search.aggregations.AggregationBuilders;
|
|
|
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation;
|
|
|
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation.Bucket;
|
|
|
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
|
|
|
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
...
|
...
|
@@ -56,23 +54,21 @@ public class BrandWithShopsService implements ApplicationEventPublisherAware { |
|
|
this.publisher = applicationEventPublisher;
|
|
|
}
|
|
|
|
|
|
@SearchCacheAble(cacheInMinute = 15, cacheName = "BRANDS_WITH_SHOPS", excludeParams = {"viewNum", "uid", "udid"})
|
|
|
//@SearchCacheAble(cacheInMinute = 15, cacheName = "BRANDS_WITH_SHOPS", excludeParams = {"viewNum", "uid", "udid"})
|
|
|
public SearchApiResult brandsWithShops(Map<String, String> paramMap) {
|
|
|
try {
|
|
|
logger.info("[func=brandsWithShops][param={}][begin={}]", paramMap.toString(), System.currentTimeMillis());
|
|
|
// 1、构造查询参数
|
|
|
SearchParam searchParam = searchParamHelper.buildDefault(paramMap);
|
|
|
// 2、构造聚合参数
|
|
|
List<AbstractAggregationBuilder<?>> list = new ArrayList<AbstractAggregationBuilder<?>>();
|
|
|
// 2.1)父聚合:brandAlif
|
|
|
TermsAggregationBuilder brandAlifAgg = AggregationBuilders.terms("brandAlifAgg").field(ProductIndexEsField.brandAlif).size(200).order(Terms.Order.term(true));
|
|
|
// 2.2)子聚合:brandId
|
|
|
TermsAggregationBuilder brandIdAgg = AggregationBuilders.terms("brandIdAgg").field(ProductIndexEsField.brandId).size(1000);
|
|
|
// 2.3)孙聚合:shop
|
|
|
List<AbstractAggregationBuilder<?>> list = new ArrayList<>();
|
|
|
// 2.1)父聚合:brandId
|
|
|
TermsAggregationBuilder brandIdAgg = AggregationBuilders.terms("brandIdAgg").field(ProductIndexEsField.brandId).size(3000);
|
|
|
// 2.2)子聚合:shopId
|
|
|
TermsAggregationBuilder shopAgg = AggregationBuilders.terms("shopIdAgg").field(ProductIndexEsField.shopId).size(30);
|
|
|
// 2.4)曾孙聚合:是否全球购
|
|
|
// 2.3)孙聚合:是否全球购
|
|
|
TermsAggregationBuilder globalAgg = AggregationBuilders.terms("isGlobalAgg").field(ProductIndexEsField.isGlobal).size(5);
|
|
|
list.add(brandAlifAgg.subAggregation(brandIdAgg.subAggregation(shopAgg.subAggregation(globalAgg))));
|
|
|
list.add(brandIdAgg.subAggregation(shopAgg.subAggregation(globalAgg)));
|
|
|
searchParam.setAggregationBuilders(list);
|
|
|
|
|
|
// 3、查询ES
|
...
|
...
|
@@ -82,12 +78,14 @@ public class BrandWithShopsService implements ApplicationEventPublisherAware { |
|
|
return searchApiResult.setCode(500);
|
|
|
}
|
|
|
Map<String, Aggregation> aggregationResult = searchResult.getAggMaps();
|
|
|
if (!aggregationResult.containsKey("brandAlifAgg")) {
|
|
|
if (!aggregationResult.containsKey("brandIdAgg")) {
|
|
|
return searchApiResult;
|
|
|
}
|
|
|
// 4、构造返回结果并加入缓存
|
|
|
Map<String, List<BrandShopInfo>> brandId2ShopInfoList = this.buildBrandId2ShopInfoList(aggregationResult);
|
|
|
|
|
|
// 4、构造返回结果
|
|
|
JSONObject result = new JSONObject();
|
|
|
result.put("brands", makeBrandResponse(((MultiBucketsAggregation) aggregationResult.get("brandAlifAgg"))));
|
|
|
result.put("brands", buildRealResults(brandId2ShopInfoList));
|
|
|
return searchApiResult.setData(result);
|
|
|
} catch (Exception e) {
|
|
|
publisher.publishEvent(new SearchEvent(EventReportEnum.SEARCHCONTROLLER_BRANDS.getEventName(), EventReportEnum.SEARCHCONTROLLER_BRANDS.getFunctionName(),
|
...
|
...
|
@@ -96,101 +94,120 @@ public class BrandWithShopsService implements ApplicationEventPublisherAware { |
|
|
}
|
|
|
}
|
|
|
|
|
|
private MultiBucketsAggregation getMultiBucketsAggregation(Bucket bucket, String aggName) {
|
|
|
return (MultiBucketsAggregation) bucket.getAggregations().asMap().get(aggName);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 制作品牌报文
|
|
|
*/
|
|
|
private Map<String, JSONArray> makeBrandResponse(MultiBucketsAggregation aggregation) {
|
|
|
// 1)获取每个brandAlif-->brandId->List<BrandShopInfo>
|
|
|
Map<String, Map<String, List<BrandShopInfo>>> brandAlif2BrandShopInfos = new LinkedHashMap<String, Map<String, List<BrandShopInfo>>>();
|
|
|
for (Bucket brandAlifBucket : aggregation.getBuckets()) {
|
|
|
String brandAlif = brandAlifBucket.getKeyAsString();
|
|
|
Map<String, List<BrandShopInfo>> brandWithShopsListMap = new LinkedHashMap<String, List<BrandShopInfo>>();
|
|
|
MultiBucketsAggregation brandIdAgg = this.getMultiBucketsAggregation(brandAlifBucket, "brandIdAgg");
|
|
|
for (Bucket brandIdBucket : brandIdAgg.getBuckets()) {
|
|
|
String brandId = brandIdBucket.getKeyAsString();
|
|
|
List<BrandShopInfo> brandShopInfoList = new ArrayList<BrandShopInfo>();
|
|
|
MultiBucketsAggregation shopIdAggs = this.getMultiBucketsAggregation(brandIdBucket, "shopIdAgg");
|
|
|
for (Bucket shopIdBucket : shopIdAggs.getBuckets()) {
|
|
|
String shopId = shopIdBucket.getKeyAsString();
|
|
|
MultiBucketsAggregation isGlobalAgg = this.getMultiBucketsAggregation(shopIdBucket, "isGlobalAgg");
|
|
|
for (Bucket isGlobalBucket : isGlobalAgg.getBuckets()) {
|
|
|
String isGlobal = isGlobalBucket.getKeyAsString();
|
|
|
BrandShopInfo brandShopInfo = new BrandShopInfo(shopId, isGlobal);
|
|
|
if (this.isBrandShopInfoLegal(brandShopInfo)) {
|
|
|
brandShopInfoList.add(brandShopInfo);
|
|
|
}
|
|
|
// 构造每个brandId对应的List<BrandShopInfo>
|
|
|
private Map<String, List<BrandShopInfo>> buildBrandId2ShopInfoList(Map<String, Aggregation> aggregationResult) {
|
|
|
Map<String, List<BrandShopInfo>> results = new LinkedHashMap<>();
|
|
|
if (!aggregationResult.containsKey("brandIdAgg")) {
|
|
|
return results;
|
|
|
}
|
|
|
MultiBucketsAggregation brandIdAgg = ((MultiBucketsAggregation) aggregationResult.get("brandIdAgg"));
|
|
|
for (Bucket brandIdBucket : brandIdAgg.getBuckets()) {
|
|
|
String brandId = brandIdBucket.getKeyAsString();
|
|
|
List<BrandShopInfo> brandShopInfoList = new ArrayList<>();
|
|
|
MultiBucketsAggregation shopIdAggs = (MultiBucketsAggregation) brandIdBucket.getAggregations().asMap().get("shopIdAgg");
|
|
|
for (Bucket shopIdBucket : shopIdAggs.getBuckets()) {
|
|
|
String shopId = shopIdBucket.getKeyAsString();
|
|
|
MultiBucketsAggregation isGlobalAgg = (MultiBucketsAggregation) shopIdBucket.getAggregations().asMap().get("isGlobalAgg");
|
|
|
for (Bucket isGlobalBucket : isGlobalAgg.getBuckets()) {
|
|
|
String isGlobal = isGlobalBucket.getKeyAsString();
|
|
|
BrandShopInfo brandShopInfo = new BrandShopInfo(shopId, isGlobal);
|
|
|
if (this.isBrandShopInfoLegal(brandShopInfo)) {
|
|
|
brandShopInfoList.add(brandShopInfo);
|
|
|
}
|
|
|
}
|
|
|
brandWithShopsListMap.put(brandId, brandShopInfoList);
|
|
|
}
|
|
|
brandAlif2BrandShopInfos.put(brandAlif, brandWithShopsListMap);
|
|
|
results.put(brandId, brandShopInfoList);
|
|
|
}
|
|
|
// 2)获取所有的品牌id和有货单品点的店铺id
|
|
|
List<String> brandIds = new ArrayList<String>();
|
|
|
List<String> shopIds = new ArrayList<String>();
|
|
|
List<String> globalBrandIds = new ArrayList<String>();
|
|
|
return results;
|
|
|
}
|
|
|
|
|
|
for (Map.Entry<String, Map<String, List<BrandShopInfo>>> entry : brandAlif2BrandShopInfos.entrySet()) {
|
|
|
Map<String, List<BrandShopInfo>> brandShopInfoMap = entry.getValue();
|
|
|
for (Map.Entry<String, List<BrandShopInfo>> brandShopInfoMapEntry : brandShopInfoMap.entrySet()) {
|
|
|
brandIds.add(brandShopInfoMapEntry.getKey());
|
|
|
List<BrandShopInfo> brandShopInfoList = brandShopInfoMapEntry.getValue();
|
|
|
for (BrandShopInfo brandShopInfo : brandShopInfoList) {
|
|
|
shopIds.add(brandShopInfo.getShopId());
|
|
|
if ("Y".equals(brandShopInfo.getIsGlobal())) {
|
|
|
globalBrandIds.add(brandShopInfoMapEntry.getKey());
|
|
|
}
|
|
|
private Map<String, JSONArray> buildRealResults(Map<String, List<BrandShopInfo>> brandId2ShopInfoList) {
|
|
|
// 1)获取所有的品牌id和有货单品店的店铺id
|
|
|
List<String> brandIds = new ArrayList<>();
|
|
|
List<String> shopIds = new ArrayList<>();
|
|
|
List<String> globalBrandIds = new ArrayList<>();
|
|
|
for (Map.Entry<String, List<BrandShopInfo>> brandShopInfoMapEntry : brandId2ShopInfoList.entrySet()) {
|
|
|
brandIds.add(brandShopInfoMapEntry.getKey());
|
|
|
List<BrandShopInfo> brandShopInfoList = brandShopInfoMapEntry.getValue();
|
|
|
for (BrandShopInfo brandShopInfo : brandShopInfoList) {
|
|
|
shopIds.add(brandShopInfo.getShopId());
|
|
|
if ("Y".equals(brandShopInfo.getIsGlobal())) {
|
|
|
globalBrandIds.add(brandShopInfoMapEntry.getKey());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
// 3)获取所有的品牌数据
|
|
|
Map<String, Map<String, Object>> brandInfoMap = brandIndexBaseService.getBrandMapByIds(brandIds,true);
|
|
|
// 4)获取所有的全球购品牌数据
|
|
|
|
|
|
// 2)获取所有的品牌数据
|
|
|
Map<String, Map<String, Object>> brandInfoMap = brandIndexBaseService.getBrandMapByIds(brandIds, true);
|
|
|
// 3)获取所有的全球购品牌数据
|
|
|
Map<String, Map<String, Object>> globalBrandInfoMap = brandIndexBaseService.getGlobalBrandMapByIds(globalBrandIds, 1);
|
|
|
// 5)获取所有的有货店铺数据
|
|
|
// 4)获取所有的有货店铺数据
|
|
|
Map<String, Map<String, Object>> shopInfoMap = shopsIndexBaseService.getShopsMapByIds(shopIds);
|
|
|
|
|
|
// 6)构造真正的数据
|
|
|
Map<String, JSONArray> result = new LinkedHashMap<String, JSONArray>();
|
|
|
for (Map.Entry<String, Map<String, List<BrandShopInfo>>> aliafEntry : brandAlif2BrandShopInfos.entrySet()) {
|
|
|
String brandAlif = aliafEntry.getKey();
|
|
|
List<JSONObject> brandWithShopsInfo = new ArrayList<JSONObject>();
|
|
|
for (Map.Entry<String, List<BrandShopInfo>> entry : aliafEntry.getValue().entrySet()) {
|
|
|
String brandId = entry.getKey();
|
|
|
Map<String, Object> brandInfo = brandInfoMap.get(brandId);
|
|
|
if (brandInfo == null || MapUtils.getIntValue(brandInfo, "status", 0) != 1) {
|
|
|
continue;
|
|
|
}
|
|
|
JSONObject shop_info = new JSONObject();
|
|
|
List<BrandShopInfo> brandShopInfoList = entry.getValue();
|
|
|
JSONArray shop_yoho_list = this.getYohoShopInfo(brandShopInfoList, shopInfoMap);
|
|
|
shop_info.put("yoho_shop_list", shop_yoho_list);
|
|
|
shop_info.put("yoho_shop_count", shop_yoho_list.size());
|
|
|
JSONArray global_brand_List = this.getGlobalBrandList(brandShopInfoList, brandId, globalBrandInfoMap);
|
|
|
shop_info.put("global_brand_List", global_brand_List);
|
|
|
shop_info.put("global_brand_count", global_brand_List.size());
|
|
|
brandInfo.put("shop_info", shop_info);
|
|
|
brandWithShopsInfo.add(new JSONObject(brandInfo));
|
|
|
// 5)构建brandWithShopsInfoList
|
|
|
List<JSONObject> brandWithShopsInfoList = new ArrayList<>();
|
|
|
for (Map.Entry<String, List<BrandShopInfo>> entry : brandId2ShopInfoList.entrySet()) {
|
|
|
String brandId = entry.getKey();
|
|
|
Map<String, Object> brandInfo = brandInfoMap.get(brandId);
|
|
|
if (brandInfo == null || MapUtils.getIntValue(brandInfo, "status", 0) != 1) {
|
|
|
continue;
|
|
|
}
|
|
|
if (brandWithShopsInfo.isEmpty()) {
|
|
|
JSONObject shop_info = new JSONObject();
|
|
|
List<BrandShopInfo> brandShopInfoList = entry.getValue();
|
|
|
JSONArray shop_yoho_list = this.getYohoShopInfo(brandShopInfoList, shopInfoMap);
|
|
|
shop_info.put("yoho_shop_list", shop_yoho_list);
|
|
|
shop_info.put("yoho_shop_count", shop_yoho_list.size());
|
|
|
JSONArray global_brand_List = this.getGlobalBrandList(brandShopInfoList, brandId, globalBrandInfoMap);
|
|
|
shop_info.put("global_brand_List", global_brand_List);
|
|
|
shop_info.put("global_brand_count", global_brand_List.size());
|
|
|
brandInfo.put("shop_info", shop_info);
|
|
|
brandWithShopsInfoList.add(new JSONObject(brandInfo));
|
|
|
}
|
|
|
|
|
|
// 6) 出现STORE by NIGO®时添加HUMAN_MADE的壳子【439->2512】
|
|
|
this.addHUMAN_MADE(brandWithShopsInfoList);
|
|
|
|
|
|
// 7) 按brand_name_for_sort整体排序
|
|
|
Collections.sort(brandWithShopsInfoList, (o1, o2) -> MapUtils.getString(o1, "brand_name_for_sort", "#").compareToIgnoreCase(MapUtils.getString(o2, "brand_name_for_sort", "#")));
|
|
|
|
|
|
//8) 除brand_name_for_sort, 并按brand_alif分组并移
|
|
|
Map<String, JSONArray> realResults = new TreeMap<>();
|
|
|
for (JSONObject brandWithShopsInfo : brandWithShopsInfoList) {
|
|
|
brandWithShopsInfo.remove("brand_name_for_sort");
|
|
|
String brand_alif = MapUtils.getString(brandWithShopsInfo, "brand_alif", "");
|
|
|
if (StringUtils.isBlank(brand_alif)) {
|
|
|
continue;
|
|
|
}
|
|
|
//按brand_name_for_sort排序
|
|
|
Collections.sort(brandWithShopsInfo, (o1, o2) ->
|
|
|
MapUtils.getString(o1, "brand_name_for_sort", "#").compareToIgnoreCase(MapUtils.getString(o2, "brand_name_for_sort", "#"))
|
|
|
);
|
|
|
JSONArray brandWithShopsInfoJsonArray = new JSONArray();
|
|
|
for (JSONObject brandInfo : brandWithShopsInfo) {
|
|
|
brandInfo.remove("brand_name_for_sort");
|
|
|
brandWithShopsInfoJsonArray.add(brandInfo);
|
|
|
JSONArray jsonArray = realResults.computeIfAbsent(brand_alif, k -> new JSONArray());
|
|
|
jsonArray.add(brandWithShopsInfo);
|
|
|
}
|
|
|
return realResults;
|
|
|
}
|
|
|
|
|
|
// 出现STORE by NIGO®时添加HUMAN_MADE的壳子【439->2512】
|
|
|
private void addHUMAN_MADE(List<JSONObject> brandWithShopsInfoList) {
|
|
|
JSONObject HUMAN_MADE = null;
|
|
|
for (JSONObject brandWithShopsInfo : brandWithShopsInfoList) {
|
|
|
int brandId = MapUtils.getIntValue(brandWithShopsInfo, "id", 0);
|
|
|
//如果有HUMAN_MADE[2512],直接返回不添加
|
|
|
if (brandId == 2512) {
|
|
|
return;
|
|
|
}
|
|
|
//如果有STORE by NIGO®[439],则生成HUMAN_MADE的壳子
|
|
|
if (brandId == 1036) {
|
|
|
HUMAN_MADE = new JSONObject();
|
|
|
HUMAN_MADE.putAll(brandWithShopsInfo);
|
|
|
HUMAN_MADE.put("brand_alif", "H");//分组
|
|
|
HUMAN_MADE.put("brand_name", "HUMAN MADE");//显示
|
|
|
HUMAN_MADE.put("brand_name_en", "HUMAN MADE");
|
|
|
HUMAN_MADE.put("brand_name_cn", "HUMAN MADE");
|
|
|
HUMAN_MADE.put("brand_name_for_sort", "humanmade");//排序
|
|
|
continue;
|
|
|
}
|
|
|
result.put(brandAlif, brandWithShopsInfoJsonArray);
|
|
|
}
|
|
|
return result;
|
|
|
if (HUMAN_MADE != null) {
|
|
|
brandWithShopsInfoList.add(HUMAN_MADE);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
...
|
...
|
|