Authored by wangnan9279

ufo系列列表

package com.yoho.search.common.utils;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
/**
* 图片URL拼接的辅助接口
* @author mali
*
*/
public class UfoImageUrlAssist {
private static final String INIT_POSITION = "center";
private static final String INIT_BACKGROUND = "d2hpdGU=";
private static final String INIT_SIZE = "source";
private static final Logger logger = LoggerFactory.getLogger(ImageUrlAssist.class);
/**
* 图片尺寸字符串的分隔符
*/
private static final String SEPRATOR_SIZE = "x";
/**
* 获取图片的完整路径 包含参数
* @param imageUrl 相对路径
* @param bucket
* @param position
* @param background
* @return 图片的完整路径
*/
public static String getAllProductPicUrl(Object imageUrl, String bucket, String position, String background) {
if(logger.isDebugEnabled()){
logger.debug("getAllProductPicUrl imageUrl:{},bucket:{},position:{},background:{}", imageUrl, bucket, position, background);
}
if (!(imageUrl instanceof String) || StringUtils.isEmpty((String)imageUrl)) {
return "";
}
if (((String)imageUrl).startsWith("http://")) {
return (String)imageUrl;
}
if (StringUtils.isEmpty(background)) {
background = INIT_BACKGROUND;
}
if (StringUtils.isEmpty(position)) {
position = INIT_POSITION;
}
return getUrl((String)imageUrl, bucket, null, null) + "?imageMogr2/thumbnail/{width}x{height}/background/"
+ background + "/position/" + position + "/quality/80";
}
/**
* 获取图片的路径,不含参数
* @param imageUrl
* @param bucket
* @return
*/
public static String getUrl(String imageUrl, String bucket, String source, Integer mode) {
if (StringUtils.isEmpty(imageUrl)) {
return "";
}
source = StringUtils.isEmpty(source) ? INIT_SIZE : source;
mode = null == mode ? 1 : mode;
Integer width = null;
Integer height = null;
if (StringUtils.isEmpty(source) && !INIT_SIZE.equals(source)) {
String[] split = source.split(SEPRATOR_SIZE);
if (split.length == 2) {
try {
width = Integer.valueOf(split[0]);
height = Integer.valueOf(split[1]);
} catch (NumberFormatException e) {
logger.warn("The source of goodsPic is not number. imageUrl is " + imageUrl + "; source : " + source, e);
}
}
}
String domain = getDomain(imageUrl);
if (StringUtils.isEmpty(domain)) {
return "";
}
return getImgPrivateUrl(bucket + imageUrl, width, height, mode, domain);
}
/**
* 获取私有的图片地址
* @param fileName
* @param width
* @param height
* @param mode
* @param domain
* @return
*/
private static String getImgPrivateUrl(String fileName, Integer width, Integer height, Integer mode, String domain) {
if (null == mode) {
mode = 1;
}
if (StringUtils.isEmpty(domain)) {
domain = "yhfair.qiniudn.com";
}
return makeRequest("http://" + domain + "/" + fileName.replaceAll("%2F", "/"), mode, width, height, domain, null, null);
}
/**
* 拼接图片的URL参数
* @param baseUrl
* @param mode
* @param width
* @param height
* @param domain
* @param quality
* @param format
* @return
*/
private static String makeRequest(String baseUrl, Integer mode, Integer width, Integer height, String domain,
String quality, String format) {
StringBuilder sb = new StringBuilder();
if (null != mode) {
sb.append(mode);
}
if (null != width) {
sb.append("/w/").append(width);
}
if (null != height) {
sb.append("/h/").append(height);
}
if (null != quality) {
sb.append("/q/").append(quality);
}
if (null != format) {
sb.append("/format/").append(format);
}
if (0 == sb.length()) {
return baseUrl;
}
if (null == width || null == height) {
return baseUrl;
}
return baseUrl + "?imageView/" + sb.toString();
}
public static String getUrlWhitImageView2(String url) {
return url + "?imageView2/{mode}/w/{width}/h/{height}/q/60";
}
private static String getDomain(String imageUrl) {
if (imageUrl.length() < 17) {
return "";
}
String node = imageUrl.substring(15, 17);
List<String> domainList = getDomainList(node);
if (domainList.isEmpty()) {
return "";
}
return domainList.get(1); // 默认域名http(s)://img11.static.yhbimg.com
}
/**
* 图片的节点服务器列表
* @param node
* @return
*/
private static List<String> getDomainList(String node) {
if ("01".equals(node)) {
return Lists.newArrayList("img10.static.yhbimg.com", "img11.static.yhbimg.com");
}else if("02".equals(node)) {
return Lists.newArrayList("img12.static.yhbimg.com", "img13.static.yhbimg.com");
}
return new ArrayList<String>(0);
}
}
... ...
package com.yoho.search.restapi.ufo;
import com.yoho.search.common.utils.HttpServletRequestUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.scene.ufo.UfoBrandListService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* @author wangnan
* @version 2018/12/13
*/
@Controller
public class UfoBrandListController {
@Autowired
private UfoBrandListService ufoBrandListService;
@RequestMapping(method = RequestMethod.GET, value = "/ufo/brandList")
@ResponseBody
public SearchApiResult brandList(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return ufoBrandListService.aggAllBrandList(paramMap);
}
}
... ...
... ... @@ -2,9 +2,7 @@ package com.yoho.search.restapi.ufo;
import com.yoho.search.common.utils.HttpServletRequestUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.scene.shopbrand.UfoAggBrandService;
import com.yoho.search.service.scene.ufo.UfoProductListService;
import com.yoho.search.service.scene.ufo.UfoSelectionsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
... ... @@ -19,14 +17,10 @@ import java.util.Map;
* @version 2018/9/14
*/
@Controller
public class UfoController {
public class UfoProductListController {
@Autowired
private UfoProductListService ufoProductListService;
@Autowired
private UfoAggBrandService ufoAggBrandService;
@Autowired
private UfoSelectionsService ufoSelectionsService;
@RequestMapping(method = RequestMethod.GET, value = "/ufo/productList")
@ResponseBody
... ... @@ -35,27 +29,6 @@ public class UfoController {
return ufoProductListService.productList(paramMap);
}
@RequestMapping(method = RequestMethod.GET, value = "/ufo/brandList")
@ResponseBody
public SearchApiResult brandList(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return ufoAggBrandService.aggAllBrandList(paramMap);
}
@RequestMapping(method = RequestMethod.GET, value = "/ufo/selectionList")
@ResponseBody
public SearchApiResult selectionList(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return ufoSelectionsService.getSelectionsForApp(paramMap);
}
@RequestMapping(method = RequestMethod.GET, value = "/ufo/recommendList")
@ResponseBody
public SearchApiResult recommendList(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return ufoProductListService.recommendList(paramMap);
}
@RequestMapping(method = RequestMethod.GET, value = "/ufo/productListForPlatform")
@ResponseBody
public SearchApiResult productListForPlatform(HttpServletRequest request) {
... ...
package com.yoho.search.restapi.ufo;
import com.yoho.search.common.utils.HttpServletRequestUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.scene.ufo.UfoProductListService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* @author wangnan
* @version 2018/12/13
*/
@Controller
public class UfoRecommendListController {
@Autowired
private UfoProductListService ufoProductListService;
@RequestMapping(method = RequestMethod.GET, value = "/ufo/recommendList")
@ResponseBody
public SearchApiResult recommendList(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return ufoProductListService.recommendList(paramMap);
}
}
... ...
package com.yoho.search.restapi.ufo;
import com.yoho.search.common.utils.HttpServletRequestUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.scene.ufo.UfoSelectionListService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* @author wangnan
* @version 2018/12/13
*/
@Controller
public class UfoSelectionListController {
@Autowired
private UfoSelectionListService ufoSelectionListService;
@RequestMapping(method = RequestMethod.GET, value = "/ufo/selectionList")
@ResponseBody
public SearchApiResult selectionList(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return ufoSelectionListService.getSelectionsForApp(paramMap);
}
}
... ...
package com.yoho.search.restapi.ufo;
import com.yoho.search.common.utils.HttpServletRequestUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.scene.ufo.UfoSeriesListService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* @author wangnan
* @version 2018/12/13
*/
@Controller
public class UfoSeriesListController {
@Autowired
private UfoSeriesListService ufoSeriesListService;
@RequestMapping(method = RequestMethod.GET, value = "/ufo/seriesList")
@ResponseBody
public SearchApiResult seriesList(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return ufoSeriesListService.searchSeriesList(paramMap);
}
}
... ...
... ... @@ -105,4 +105,18 @@ public class UfoBrandIndexBaseService {
});
}
public Map<String, String> getBrandLogoMapByIds(Collection<?> brandIds) {
Map<String, String> brandLogoMap = new HashMap<>();
try {
List<Map<String, Object>> multiGetResults = searchCommonService.doMultiGetCommon(UFO_BRAND_INDEX_NAME, brandIds);
for (Map<String, Object> esMap : multiGetResults) {
brandLogoMap.put(MapUtils.getString(esMap, "id", "0"), MapUtils.getString(esMap, "brandLogo", ""));
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return brandLogoMap;
}
}
... ...
package com.yoho.search.service.scene.shopbrand;
package com.yoho.search.service.scene.ufo;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
... ... @@ -30,8 +30,8 @@ import java.util.Map;
* @version 2018/9/17
*/
@Service
public class UfoAggBrandService {
private static final Logger logger = LoggerFactory.getLogger(UfoAggBrandService.class);
public class UfoBrandListService {
private static final Logger logger = LoggerFactory.getLogger(UfoBrandListService.class);
@Autowired
private UfoSearchQueryHelper ufoSearchQueryHelper;
... ...
... ... @@ -32,9 +32,9 @@ import java.util.Map;
* @version 2018/9/17
*/
@Service
public class UfoSelectionsService {
public class UfoSelectionListService {
private static final Logger logger = LoggerFactory.getLogger(UfoSelectionsService.class);
private static final Logger logger = LoggerFactory.getLogger(UfoSelectionListService.class);
@Autowired
private UfoSearchQueryHelper ufoSearchQueryHelper;
... ...
package com.yoho.search.service.scene.ufo;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.aop.cache.SearchCacheAble;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.base.utils.SearchCollectionUtils;
import com.yoho.search.base.utils.UfoProductIndexEsField;
import com.yoho.search.common.SearchCommonService;
import com.yoho.search.common.utils.ImageUrlAssist;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.helper.UfoSearchQueryHelper;
import com.yoho.search.service.index.UfoBrandIndexBaseService;
import org.apache.commons.collections.MapUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
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.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.tophits.TopHits;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* @author wangnan
* @version 2018/12/13
*/
@Service
public class UfoSeriesListService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private static final String firstAggName = "FirstAgg";
private static final String secondAggName = "SecondAgg";
@Autowired
private UfoSearchQueryHelper ufoSearchQueryHelper;
@Autowired
private SearchCommonService searchCommonService;
@Autowired
private UfoBrandIndexBaseService ufoBrandIndexBaseService;
@SearchCacheAble(cacheInMinute = 10, cacheName = "UFO_SERIES_LIST", excludeParams = {"order", "page", "viewNum"})
public SearchApiResult searchSeriesList(Map<String, String> paramMap) {
try {
SearchParam searchParam = new SearchParam();
searchParam.setSize(0);
//1.构造过滤
BoolQueryBuilder boolFilter = ufoSearchQueryHelper.constructFilterBuilder(paramMap, null);
searchParam.setFiter(boolFilter);
//2.构造聚合
List<AbstractAggregationBuilder<?>> list = new ArrayList<>();
// 2.1构造父聚合
TermsAggregationBuilder firstAggregationBuilder = AggregationBuilders.terms(firstAggName).field(UfoProductIndexEsField.brandId).order(Terms.Order.term(true)).size(1000);
// 2.2添加子聚合
TermsAggregationBuilder secondAggregationBuilder = AggregationBuilders.terms(secondAggName).field(UfoProductIndexEsField.seriesId).order(Terms.Order.term(true)).size(1000);
firstAggregationBuilder.subAggregation(secondAggregationBuilder);
// 2.3添加孙聚合
String[] includeField = SearchCollectionUtils.listToArray(Arrays.asList(UfoProductIndexEsField.brandId, UfoProductIndexEsField.seriesId, UfoProductIndexEsField.seriesName, UfoProductIndexEsField.defaultImages));
secondAggregationBuilder.subAggregation(AggregationBuilders.topHits("product").fetchSource(includeField, null).size(1));
list.add(firstAggregationBuilder);
searchParam.setAggregationBuilders(list);
//3.执行搜索
final String indexName = ISearchConstants.INDEX_NAME_UFO_PRODUCT_INDEX;
SearchResult searchResult = searchCommonService.doSearch(indexName, searchParam);
if (searchResult == null || searchResult.getAggMaps() == null) {
return new SearchApiResult().setData(null).setCode(500);
}
Map<String, Aggregation> aggregationResult = searchResult.getAggMaps();
if (!aggregationResult.containsKey(firstAggName)) {
return new SearchApiResult().setData(null).setCode(500);
}
//4.构造返回数据结构
List<Map<String, Object>> seriesList = this.getSeriesList(aggregationResult);
JSONObject jsonObject = new JSONObject();
jsonObject.put("series_list", seriesList);
jsonObject.put("total", seriesList.size());
return new SearchApiResult().setData(jsonObject);
} catch (Exception e) {
logger.error(e.getMessage(), e);
return new SearchApiResult().setData(null).setCode(500);
}
}
private List<Map<String, Object>> getSeriesList(Map<String, Aggregation> aggregationResult) {
List<Map<String, Object>> returnList = new ArrayList<>();
//brand层聚合
MultiBucketsAggregation brandIdAgg = ((MultiBucketsAggregation) aggregationResult.get(firstAggName));
//获取brandId->brandLogo映射
Map<String, String> brandLogoMap = this.buildBrandLogoMap(brandIdAgg);
for (MultiBucketsAggregation.Bucket brandIdBucket : brandIdAgg.getBuckets()) {
String brandId = brandIdBucket.getKeyAsString();
JSONArray seriesArray = new JSONArray();
//series层聚合
MultiBucketsAggregation seriesIdAgg = (MultiBucketsAggregation) brandIdBucket.getAggregations().asMap().get(secondAggName);
for (MultiBucketsAggregation.Bucket shopIdBucket : seriesIdAgg.getBuckets()) {
if (!shopIdBucket.getAggregations().getAsMap().containsKey("product")) {
continue;
}
//series下面取一个product
TopHits topHits = shopIdBucket.getAggregations().get("product");
Map<String, Object> source = getTopHitResult(topHits);
seriesArray.add(this.buildSeriesReturnObject(source));
}
Map<String, Object> brandMap = this.buildBrandReturnMap(brandId, brandLogoMap.get(brandId), seriesArray);
returnList.add(brandMap);
}
return returnList;
}
private Map<String, String> buildBrandLogoMap(MultiBucketsAggregation brandIdAgg) {
Set<String> brandIdSet = new HashSet<>();
for (MultiBucketsAggregation.Bucket brandIdBucket : brandIdAgg.getBuckets()) {
brandIdSet.add(brandIdBucket.getKeyAsString());
}
return ufoBrandIndexBaseService.getBrandLogoMapByIds(brandIdSet);
}
private Map<String, Object> buildBrandReturnMap(String brandId, String brandLogo, JSONArray seriesArray) {
Map<String, Object> brandMap = new LinkedHashMap<>();
brandMap.put("brand_id", brandId);
brandMap.put("brand_logo", ImageUrlAssist.getAllProductPicUrl(brandLogo, "brandLogo", "center", "d2hpdGU="));
brandMap.put("brand_series", seriesArray);
return brandMap;
}
private JSONObject buildSeriesReturnObject(Map<String, Object> source) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("series_id", MapUtils.getString(source, UfoProductIndexEsField.seriesId, ""));
jsonObject.put("series_name", MapUtils.getString(source, UfoProductIndexEsField.seriesName, ""));
String seriesImage = MapUtils.getString(source, UfoProductIndexEsField.defaultImages, "");
jsonObject.put("series_image", ImageUrlAssist.getAllProductPicUrl(seriesImage, "goodsimg", "center", "d2hpdGU="));
return jsonObject;
}
private Map<String, Object> getTopHitResult(TopHits topHits) {
if (topHits == null) {
return null;
}
SearchHits hits = topHits.getHits();
if (hits.getHits() == null || hits.getHits().length == 0) {
return null;
}
SearchHit hit = hits.getHits()[0];
return hit.getSource();
}
}
... ...