Authored by hugufei

BrandWithShopsService接口优化

... ... @@ -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);
}
}
/**
... ...