Authored by foxxy

Merge branch 'master' into pt

Showing 46 changed files with 1320 additions and 577 deletions
package com.yoho.search.common.interceptor;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
... ... @@ -12,6 +13,7 @@ import org.springframework.web.servlet.ModelAndView;
import com.yoho.core.common.monitor.ThreadProfile;
import com.yoho.core.common.utils.HttpRequestUtils;
import com.yoho.search.base.monitor.PerformanceMonitor;
import com.yoho.search.common.downgrade.DownGradeService;
import com.yoho.search.common.utils.HttpServletRequestUtils;
... ... @@ -23,14 +25,21 @@ import com.yoho.search.common.utils.HttpServletRequestUtils;
public class ControllerCostInterceptor implements HandlerInterceptor {
private static final Logger CONTROLLER_COST = LoggerFactory.getLogger("CONTROLLER_COST");
private static final Logger CONTROLLER_PERFORMANCE = LoggerFactory.getLogger("CONTROLLER_PERFORMANCE");
private static final ThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<Long>("ThreadLocal StartTime");
@Autowired
private PerformanceMonitor monitor;
@Autowired
private DownGradeService downGradeService;
private PerformanceMonitor monitor;
@PostConstruct
void init(){
monitor = new PerformanceMonitor("CONTROLLER_PERFORMANCE",CONTROLLER_PERFORMANCE, 10);
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handle) throws Exception {
long beginTime = System.currentTimeMillis();// 1、开始时间
... ...
package com.yoho.search.common.interceptor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import javax.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class PerformanceMonitor {
private static final Logger logger = LoggerFactory.getLogger(PerformanceMonitor.class);
private static final Logger CONTROLLER_PERFORMANCE = LoggerFactory.getLogger("CONTROLLER_PERFORMANCE");
private AtomicLong totalVisit = new AtomicLong(0);
private AtomicLong totalCost = new AtomicLong(0);
private AtomicLong over500msCount = new AtomicLong(0);
private AtomicLong over1000msCount = new AtomicLong(0);
private final int MonitorPeriodInSecond = 10;
private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
@PostConstruct
void init() {
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
logAndClear();
}
}, 0, MonitorPeriodInSecond, TimeUnit.SECONDS);
}
private void logAndClear() {
try {
long visitCount = totalVisit.longValue();
long vostMs = totalCost.longValue();
long average = visitCount == 0 ? 0 : (vostMs / visitCount);
long over500msCnt = over500msCount.longValue();
double over500msCntPercent = visitCount == 0 ? 0 : (over500msCnt * 100L / visitCount);
long over1000msCnt = over1000msCount.longValue();
double over1000msCntPercent = visitCount == 0 ? 0 : (over1000msCnt * 100L / visitCount);
CONTROLLER_PERFORMANCE.info("Performance.Monitoring,Peroid [{}]s,totalVisit[{}],totalCost[{}] ms,AverageCost[{}]ms,over500msCount[{}][{}%],over1000msCnt[{}][{}%]", MonitorPeriodInSecond, visitCount,
vostMs, average,over500msCnt,over500msCntPercent,over1000msCnt,over1000msCntPercent);
totalVisit.set(0);
totalCost.set(0);
over500msCount.set(0);
over1000msCount.set(0);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
public void addVisitCount() {
totalVisit.incrementAndGet();
}
public void addCost(long cost) {
totalCost.addAndGet(cost);
if(cost>=1000){
over1000msCount.incrementAndGet();
}
if(cost>=500){
over500msCount.incrementAndGet();
}
}
}
package com.yoho.search.models;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
public class RecommendPromotionAggVO {
@JSONField(name = "promotion_info_id")
private int promotionInfoId;
@JSONField(name = "coverimg_url")
private String coverImgUrl;
private String title;
public int getPromotionInfoId() {
return promotionInfoId;
}
public void setPromotionInfoId(int promotionInfoId) {
this.promotionInfoId = promotionInfoId;
}
public String getCoverImgUrl() {
return coverImgUrl;
}
public void setCoverImgUrl(String coverImgUrl) {
this.coverImgUrl = coverImgUrl;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public static void main(String[] args) {
RecommendPromotionAggVO recommendPromotionAggVO = new RecommendPromotionAggVO();
recommendPromotionAggVO.setPromotionInfoId(1);
recommendPromotionAggVO.setCoverImgUrl("sdf");
recommendPromotionAggVO.setTitle("dfas");
System.out.println(JSON.toJSONString(recommendPromotionAggVO));
;
}
}
... ...
... ... @@ -12,7 +12,6 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.common.downgrade.aop.DownGradeAble;
import com.yoho.search.common.utils.HttpServletRequestUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.service.IBrandService;
... ... @@ -32,7 +31,6 @@ public class BrandController {
* @param request
* @return
*/
@DownGradeAble(key = "brandList")
@RequestMapping(method = RequestMethod.GET, value = "/brand/list")
@ResponseBody
public SearchApiResult brandList(HttpServletRequest request) {
... ... @@ -46,7 +44,6 @@ public class BrandController {
* @param request
* @return
*/
@DownGradeAble(key = "brands")
@RequestMapping(method = RequestMethod.GET, value = "/brands")
@ResponseBody
public SearchApiResult brands(HttpServletRequest request) {
... ... @@ -60,7 +57,6 @@ public class BrandController {
* @param request
* @return
*/
@DownGradeAble(key = "group_brands")
@RequestMapping(method = RequestMethod.GET, value = "/group_brands")
@ResponseBody
public SearchApiResult groupBrands(HttpServletRequest request) {
... ... @@ -74,7 +70,6 @@ public class BrandController {
* @param request
* @return
*/
@DownGradeAble(key = "new-shelve")
@RequestMapping(method = RequestMethod.GET, value = "/new-shelve")
@ResponseBody
public SearchApiResult aggProductsByBrandId(HttpServletRequest request) {
... ... @@ -88,7 +83,6 @@ public class BrandController {
* @param request
* @return
*/
@DownGradeAble(key = "new_product")
@RequestMapping(method = RequestMethod.GET, value = "/new_product")
@ResponseBody
public SearchApiResult aggProductsByBrandIdInParam(HttpServletRequest request) {
... ... @@ -124,7 +118,6 @@ public class BrandController {
* @param request
* @return
*/
@DownGradeAble(key = "/brandsWithShops")
@RequestMapping(method = RequestMethod.GET, value = "/brandsWithShops")
@ResponseBody
public SearchApiResult brandsWithShops(HttpServletRequest request) {
... ...
... ... @@ -10,7 +10,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.yoho.search.common.downgrade.aop.DownGradeAble;
import com.yoho.search.common.utils.HttpServletRequestUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.service.IAggRecommendService;
... ... @@ -40,7 +39,6 @@ public class ProductIndexController {
/**
* 聚合性别
*/
@DownGradeAble(key = "aggGender")
@RequestMapping(method = RequestMethod.GET, value = "/aggGender")
@ResponseBody
public SearchApiResult aggGender(HttpServletRequest request) {
... ... @@ -51,7 +49,6 @@ public class ProductIndexController {
/**
* 聚合年龄
*/
@DownGradeAble(key = "aggAgeLevel")
@RequestMapping(method = RequestMethod.GET, value = "/aggAgeLevel")
@ResponseBody
public SearchApiResult aggAgeLevel(HttpServletRequest request) {
... ... @@ -62,7 +59,6 @@ public class ProductIndexController {
/**
* 聚合价格
*/
@DownGradeAble(key = "aggPrice")
@RequestMapping(method = RequestMethod.GET, value = "/aggPrice")
@ResponseBody
public SearchApiResult aggPrice(HttpServletRequest request) {
... ... @@ -73,7 +69,6 @@ public class ProductIndexController {
/**
* 聚合颜色
*/
@DownGradeAble(key = "aggColor")
@RequestMapping(method = RequestMethod.GET, value = "/aggColor")
@ResponseBody
public SearchApiResult aggColor(HttpServletRequest request) {
... ... @@ -84,7 +79,6 @@ public class ProductIndexController {
/**
* 聚合风格
*/
@DownGradeAble(key = "aggStyle")
@RequestMapping(method = RequestMethod.GET, value = "/aggStyle")
@ResponseBody
public SearchApiResult aggStyle(HttpServletRequest request) {
... ... @@ -95,7 +89,6 @@ public class ProductIndexController {
/**
* 聚合规则
*/
@DownGradeAble(key = "aggStandard")
@RequestMapping(method = RequestMethod.GET, value = "/aggStandard")
@ResponseBody
public SearchApiResult aggStandard(HttpServletRequest request) {
... ... @@ -106,7 +99,6 @@ public class ProductIndexController {
/**
* 聚合尺码
*/
@DownGradeAble(key = "aggSize")
@RequestMapping(method = RequestMethod.GET, value = "/aggSize")
@ResponseBody
public SearchApiResult aggSize(HttpServletRequest request) {
... ... @@ -117,7 +109,6 @@ public class ProductIndexController {
/**
* 聚合是否新品
*/
@DownGradeAble(key = "aggNew")
@RequestMapping(method = RequestMethod.GET, value = "/aggNew")
@ResponseBody
public SearchApiResult aggNew(HttpServletRequest request) {
... ... @@ -128,7 +119,6 @@ public class ProductIndexController {
/**
* 聚合是否限量
*/
@DownGradeAble(key = "aggLimited")
@RequestMapping(method = RequestMethod.GET, value = "/aggLimited")
@ResponseBody
public SearchApiResult aggLimited(HttpServletRequest request) {
... ... @@ -139,7 +129,6 @@ public class ProductIndexController {
/**
* 聚合是否促销
*/
@DownGradeAble(key = "aggSpecialoffer")
@RequestMapping(method = RequestMethod.GET, value = "/aggSpecialoffer")
@ResponseBody
public SearchApiResult aggSpecialoffer(HttpServletRequest request) {
... ... @@ -150,7 +139,6 @@ public class ProductIndexController {
/**
* 聚合店铺
*/
@DownGradeAble(key = "aggShop")
@RequestMapping(method = RequestMethod.GET, value = "/aggShop")
@ResponseBody
public SearchApiResult aggShop(HttpServletRequest request) {
... ... @@ -161,7 +149,6 @@ public class ProductIndexController {
/**
* 从商品列表聚合关键词,随机返回关键词
*/
@DownGradeAble(key = "recommendKeyword")
@RequestMapping(method = RequestMethod.GET, value = "/recommendKeyword")
@ResponseBody
public SearchApiResult recommendKeyword(HttpServletRequest request) {
... ... @@ -172,7 +159,6 @@ public class ProductIndexController {
/**
* 获取筛选项【带提前聚合逻辑的】
*/
@DownGradeAble(key = "selectionsForPc")
@RequestMapping(method = RequestMethod.GET, value = "/selectionsForPc")
@ResponseBody
public SearchApiResult selections(HttpServletRequest request) {
... ... @@ -183,7 +169,6 @@ public class ProductIndexController {
/**
* 获取筛选项【不带提前聚合的逻辑】
*/
@DownGradeAble(key = "selectionsForApp")
@RequestMapping(method = RequestMethod.GET, value = "/selectionsForApp")
@ResponseBody
public SearchApiResult selectionsForApp(HttpServletRequest request) {
... ... @@ -194,7 +179,6 @@ public class ProductIndexController {
/**
* 获取商品数量
*/
@DownGradeAble(key = "productCount")
@RequestMapping(method = RequestMethod.GET, value = "/productCount")
@ResponseBody
public SearchApiResult productCount(HttpServletRequest request) {
... ... @@ -205,7 +189,6 @@ public class ProductIndexController {
/**
* 聚合品牌
*/
@DownGradeAble(key = "aggBrand")
@RequestMapping(method = RequestMethod.GET, value = "/aggBrand")
@ResponseBody
public SearchApiResult aggBrand(HttpServletRequest request) {
... ... @@ -216,7 +199,6 @@ public class ProductIndexController {
/**
* 聚合促销
*/
@DownGradeAble(key = "aggPromotion")
@RequestMapping(method = RequestMethod.GET, value = "/aggPromotion")
@ResponseBody
public SearchApiResult aggPromotion(HttpServletRequest request) {
... ... @@ -227,7 +209,6 @@ public class ProductIndexController {
/**
* 为用户推荐店铺
*/
@DownGradeAble(key = "recommendShop")
@RequestMapping(method = RequestMethod.GET, value = "/recommendShop")
@ResponseBody
public SearchApiResult recommendShop(HttpServletRequest request) {
... ... @@ -238,7 +219,6 @@ public class ProductIndexController {
/**
* 为用户推荐品牌
*/
@DownGradeAble(key = "aggRecommendBrand")
@RequestMapping(method = RequestMethod.GET, value = "/aggRecommendBrand")
@ResponseBody
public SearchApiResult recommendBrand(HttpServletRequest request) {
... ...
... ... @@ -10,7 +10,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.yoho.search.common.downgrade.aop.DownGradeAble;
import com.yoho.search.common.utils.HttpServletRequestUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.service.IDiscountService;
... ... @@ -52,7 +51,6 @@ public class SearchNewController {
* @param request
* @return
*/
@DownGradeAble(key = "sortgroup")
@RequestMapping(method = RequestMethod.GET, value = "/sortgroup")
@ResponseBody
public SearchApiResult sortGroup(HttpServletRequest request) {
... ... @@ -66,7 +64,6 @@ public class SearchNewController {
* @param request
* @return
*/
@DownGradeAble(key = "recent")
@RequestMapping(method = RequestMethod.GET, value = "/recent")
@ResponseBody
public SearchApiResult recent(HttpServletRequest request) {
... ... @@ -80,7 +77,6 @@ public class SearchNewController {
* @param request
* @return
*/
@DownGradeAble(key = "discount")
@RequestMapping(method = RequestMethod.GET, value = "/discount")
@ResponseBody
public SearchApiResult discount(HttpServletRequest request) {
... ...
... ... @@ -10,7 +10,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.yoho.search.common.downgrade.aop.DownGradeAble;
import com.yoho.search.common.utils.HttpServletRequestUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.service.IShopListService;
... ... @@ -33,7 +32,6 @@ public class ShopsController {
* @param request
* @return
*/
@DownGradeAble(key = "group_shops")
@RequestMapping(method = RequestMethod.GET, value = "/group_shops")
@ResponseBody
public SearchApiResult group_shops(HttpServletRequest request) {
... ... @@ -47,7 +45,6 @@ public class ShopsController {
* @param request
* @return
*/
@DownGradeAble(key = "shops")
@RequestMapping(method = RequestMethod.GET, value = "/shops")
@ResponseBody
public SearchApiResult searchShops(HttpServletRequest request) {
... ... @@ -61,7 +58,6 @@ public class ShopsController {
* @param request
* @return
*/
@DownGradeAble(key = "shopsNew")
@RequestMapping(method = RequestMethod.GET, value = "/shopsNew")
@ResponseBody
public SearchApiResult searchShopsNew(HttpServletRequest request) {
... ... @@ -75,7 +71,6 @@ public class ShopsController {
* @param request
* @return
*/
@DownGradeAble(key = "shopList")
@RequestMapping(method = RequestMethod.GET, value = "/shopList")
@ResponseBody
public SearchApiResult shopList(HttpServletRequest request) {
... ...
package com.yoho.search.restapi;
import com.yoho.search.common.downgrade.aop.DownGradeAble;
import com.yoho.search.common.utils.HttpServletRequestUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.models.SuggestApiResult;
import com.yoho.search.service.service.ISearchRecommendService;
import com.yoho.search.service.service.ISuggestService;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
... ... @@ -13,9 +10,11 @@ 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;
import com.yoho.search.common.utils.HttpServletRequestUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.models.SuggestApiResult;
import com.yoho.search.service.service.ISearchRecommendService;
import com.yoho.search.service.service.ISuggestService;
@Controller
public class SuggestController {
... ... @@ -31,7 +30,6 @@ public class SuggestController {
*
* @return
*/
@DownGradeAble(key = "suggest")
@RequestMapping(method = RequestMethod.GET, value = "/suggest")
@ResponseBody
public SuggestApiResult suggest(HttpServletRequest request) {
... ...
... ... @@ -10,7 +10,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.yoho.search.common.downgrade.aop.DownGradeAble;
import com.yoho.search.common.utils.HttpServletRequestUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.scene.BreakSizeSceneService;
... ... @@ -59,7 +58,6 @@ public class BreakSizeSceneController {
* @param request
* @return
*/
@DownGradeAble(key = "sort_sizes")
@RequestMapping(method = RequestMethod.GET, value = "/sort_sizes")
@ResponseBody
public SearchApiResult sort_sizes(HttpServletRequest request) {
... ... @@ -73,7 +71,6 @@ public class BreakSizeSceneController {
* @param request
* @return
*/
@DownGradeAble(key = "sort_size_products")
@RequestMapping(method = RequestMethod.GET, value = "/sort_size_products")
@ResponseBody
public SearchApiResult sort_size_products(HttpServletRequest request) {
... ...
... ... @@ -34,7 +34,8 @@ public class FuzzySceneController {
@ResponseBody
public SearchApiResult fuzzyProductList(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return fuzzySearchService.productList(paramMap);
SearchApiResult searchApiResult = fuzzySearchService.productList(paramMap);
return searchApiResult;
}
/**
... ...
... ... @@ -26,7 +26,7 @@ public class NewArrivalSceneController {
private NewArrivalSceneService newArrivalService;
/**
* 店铺页列表
* 新品到着列表
*
* @return
*/
... ... @@ -38,7 +38,7 @@ public class NewArrivalSceneController {
}
/**
* 店铺页筛选
* 新品到着筛选项
*
* @return
*/
... ... @@ -48,4 +48,16 @@ public class NewArrivalSceneController {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return newArrivalService.aggregations(paramMap);
}
/**
* 新品到着筛选项-RN
*
* @return
*/
@RequestMapping(method = RequestMethod.GET, value = "/newArrival/old/aggregations")
@ResponseBody
public SearchApiResult newArrivalOldAggregations(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return newArrivalService.oldAggregations(paramMap);
}
}
... ...
... ... @@ -10,7 +10,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.yoho.search.common.downgrade.aop.DownGradeAble;
import com.yoho.search.common.utils.HttpServletRequestUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.scene.ProductPoolSceneService;
... ... @@ -33,7 +32,6 @@ public class ProductPoolSceneController {
* @param request
* @return
*/
@DownGradeAble(key = "product_pool")
@RequestMapping(method = RequestMethod.GET, value = "/product_pool")
@ResponseBody
public SearchApiResult searchProductPool(HttpServletRequest request) {
... ...
package com.yoho.search.restapi.scene;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
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 com.yoho.search.common.utils.HttpServletRequestUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.scene.ReducePriceSceneService;
/**
* 最新降价的场景
* @author gufei.hu
*/
@Controller
public class ReducePriceSceneController {
@Autowired
private ReducePriceSceneService reducePriceSceneService;
/**
* 最新降价的商品列表
*
* @return
*/
@RequestMapping(method = RequestMethod.GET, value = "/reducePrice/productList")
@ResponseBody
public SearchApiResult reducePriceProductList(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return reducePriceSceneService.productList(paramMap);
}
/**
* 最新降价的筛选项
*
* @return
*/
@RequestMapping(method = RequestMethod.GET, value = "/reducePrice/old/aggregations")
@ResponseBody
public SearchApiResult reducePriceAggregations(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return reducePriceSceneService.aggregations(paramMap);
}
}
... ...
... ... @@ -10,7 +10,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.yoho.search.common.downgrade.aop.DownGradeAble;
import com.yoho.search.common.utils.HttpServletRequestUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.scene.searchlike.SearchLikeInShopService;
... ... @@ -33,7 +32,6 @@ public class SearchLikeSecneController {
@Autowired
private SearchLikeNotInShopService searchLikeNotInShopService;
@DownGradeAble(key = "searchLike")
@RequestMapping(method = RequestMethod.GET, value = "/searchLike")
@ResponseBody
public SearchApiResult searchLike(HttpServletRequest request) {
... ... @@ -41,16 +39,13 @@ public class SearchLikeSecneController {
return searchLikeService.searchLike(paramMap);
}
@DownGradeAble(key = "searchLikeInShop")
@RequestMapping(method = RequestMethod.GET, value = "/searchLikeInShop")
@ResponseBody
public SearchApiResult searchLikeInShop(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return searchLikeInShopService.searchLikeInShop(paramMap);
}
//@DownGradeAble(key = "searchLikeNotInShop")
//@CommpressAble(isCommpress=true)
@RequestMapping(method = RequestMethod.GET, value = "/searchLikeNotInShop")
@ResponseBody
public SearchApiResult searchLikeNotInShop(HttpServletRequest request) {
... ...
... ... @@ -49,4 +49,16 @@ public class ShopSceneController {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return shopSearchService.aggregations(paramMap);
}
/**
* 店铺页筛选-RN用
*
* @return
*/
@RequestMapping(method = RequestMethod.GET, value = "/shop/old/aggregations")
@ResponseBody
public SearchApiResult shopOldAggregations(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return shopSearchService.oldAggregations(paramMap);
}
}
... ...
... ... @@ -34,7 +34,8 @@ public class SortSceneController {
@ResponseBody
public SearchApiResult sortProductList(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return sortSearchService.productList(paramMap);
SearchApiResult searchApiResult = sortSearchService.productList(paramMap);
return searchApiResult;
}
/**
... ...
package com.yoho.search.service.aggregations.impls;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yoho.search.core.es.agg.IAggregation;
import com.yoho.search.service.base.index.BrandIndexBaseService;
import com.yoho.search.service.base.index.ColorIndexBaseService;
import com.yoho.search.service.base.index.ProductIndexBaseService;
import com.yoho.search.service.base.index.PromotionIndexBaseService;
import com.yoho.search.service.base.index.ShopsIndexBaseService;
import com.yoho.search.service.base.index.SizeIndexBaseService;
import com.yoho.search.service.base.index.StandardIndexBaseService;
import com.yoho.search.service.base.index.StyleIndexBaseService;
import com.yoho.search.service.base.index.*;
import com.yoho.search.service.helper.SearchAfterCacheHelper;
import com.yoho.search.service.scorer.personal.PersonalVectorFeatureSearch;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
@Service
public class AggregationFactoryService {
... ... @@ -40,6 +32,8 @@ public class AggregationFactoryService {
private PersonalVectorFeatureSearch personalVectorFeatureSearch;
@Autowired
private ProductIndexBaseService productIndexBaseService;
@Autowired
private CustomizeTagBaseService customizeTagBaseService;
public IAggregation getAgeLevelAggregation() {
return new AgeLevelAggregation();
... ... @@ -81,14 +75,14 @@ public class AggregationFactoryService {
return new RecommendBrandAggregation(brandIndexBaseService, personalVectorFeatureSearch, paramMap, brandCount);
}
public IAggregation getRecommendShopAggregation(Map<String, String> paramMap, int shopCount,int topHitCount) {
return new RecommendShopAggregation(shopsIndexBaseService,productIndexBaseService,personalVectorFeatureSearch, paramMap, shopCount,topHitCount);
public IAggregation getRecommendShopAggregation(Map<String, String> paramMap, int shopCount, int topHitCount) {
return new RecommendShopAggregation(shopsIndexBaseService, productIndexBaseService, personalVectorFeatureSearch, paramMap, shopCount, topHitCount);
}
public IAggregation getGroupBrandAggregation(String topHitOrder, int tophitCount) {
return new GroupBrandAggregation(brandIndexBaseService, productIndexBaseService, topHitOrder, tophitCount);
}
public IAggregation getGroupShopAggregation(String topHitOrder, int tophitCount) {
return new GroupShopAggregation(shopsIndexBaseService, productIndexBaseService, topHitOrder, tophitCount);
}
... ... @@ -101,6 +95,10 @@ public class AggregationFactoryService {
return new StandardAggregation(standardIndexBaseService, paramMap);
}
public IAggregation getRecommendPromotionAggregation(int promotionCount) {
return new RecommendPromotionAggregation(promotionIndexBaseService, promotionCount);
}
public IAggregation getRecentShelveDayAggregation() {
return new RecentShelveDayAggregation();
}
... ... @@ -136,4 +134,8 @@ public class AggregationFactoryService {
public IAggregation getShopAggregation(int aggCount) {
return new ShopAggregation(shopsIndexBaseService, aggCount);
}
public IAggregation getCustomizeTagAggregation(Map<String, String> paramMap) {
return new CustomizeTagAggregation(customizeTagBaseService, paramMap);
}
}
... ...
package com.yoho.search.service.aggregations.impls;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.filter.InternalFilter;
import org.elasticsearch.search.aggregations.bucket.nested.InternalNested;
import org.elasticsearch.search.aggregations.bucket.nested.NestedAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.terms.LongTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.springframework.util.CollectionUtils;
import com.yoho.search.base.utils.ConvertUtils;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.core.es.agg.AbstractAggregation;
import com.yoho.search.service.base.SearchRequestParams;
import com.yoho.search.service.base.index.CustomizeTagBaseService;
/**
* Created by wangnan on 2017/9/12.
*/
public class CustomizeTagAggregation extends AbstractAggregation {
private Map<String, String> paramMap;
private static String NESTED_PATH = ProductIndexEsField.customizeTags;
private static String SUB_AGG_NAME = "subCustomizeTagAgg";
private static int AGG_COUNT = 100;
private CustomizeTagBaseService customizeTagBaseService;
CustomizeTagAggregation(CustomizeTagBaseService colorIndexBaseService, Map<String, String> paramMap) {
this.paramMap = paramMap;
this.customizeTagBaseService = colorIndexBaseService;
}
@Override
public String aggName() {
return "customizeTagAgg";
}
@Override
public String filterName() {
return "customizeTagFilter";
}
@Override
public AbstractAggregationBuilder<?> getBuilder() {
BoolQueryBuilder boolFilter = QueryBuilders.boolQuery();
if (paramMap.containsKey(SearchRequestParams.SHOPS_PARAM_CUSTOMIZE_TAG)) {
int[] ids = ConvertUtils.stringToIntArray(paramMap.get(SearchRequestParams.SHOPS_PARAM_CUSTOMIZE_TAG), ",");
boolFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.customizeTagsId, ids));
}
AbstractAggregationBuilder<NestedAggregationBuilder> nestedAggregationBuilder = AggregationBuilders.nested(aggName(), NESTED_PATH)
.subAggregation(AggregationBuilders.filter(filterName(), boolFilter)
.subAggregation(AggregationBuilders.terms(SUB_AGG_NAME).field(ProductIndexEsField.customizeTagsId).size(AGG_COUNT).order(Terms.Order.count(false))));
return nestedAggregationBuilder;
}
@Override
public Object getAggregationResponseMap(Map<String, Aggregation> aggMaps) {
InternalNested aggregation = (InternalNested) aggMaps.get(aggName());
if (CollectionUtils.isEmpty(aggregation.getAggregations().asList())) {
return new ArrayList<>();
}
InternalFilter filter = (InternalFilter) aggregation.getAggregations().asList().get(0);
List<LongTerms.Bucket> longTerms = ((LongTerms) filter.getAggregations().asList().get(0)).getBucketsInternal();
Set<String> tagIdSet = longTerms.stream().map(e -> e.getKeyAsNumber().intValue() + "").collect(Collectors.toSet());
if (CollectionUtils.isEmpty(tagIdSet)) {
return new ArrayList<>();
}
return customizeTagBaseService.getTagListByIds(tagIdSet);
}
}
\ No newline at end of file
... ...
package com.yoho.search.service.aggregations.impls;
import com.yoho.search.base.utils.DateUtil;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.core.es.agg.AbstractAggregation;
import com.yoho.search.service.base.index.PromotionIndexBaseService;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.filter.InternalFilter;
import org.elasticsearch.search.aggregations.bucket.nested.InternalNested;
import org.elasticsearch.search.aggregations.bucket.nested.NestedAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.terms.LongTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.springframework.util.CollectionUtils;
import java.util.*;
import java.util.stream.Collectors;
public class RecommendPromotionAggregation extends AbstractAggregation {
private static final String TERM_AGGREGATION_NAME = "promotionIdAgg";
private PromotionIndexBaseService promotionIndexBaseService;
private int promotionCount;
RecommendPromotionAggregation(PromotionIndexBaseService promotionIndexBaseService, int promotionCount) {
this.promotionIndexBaseService = promotionIndexBaseService;
this.promotionCount = promotionCount;
}
public int getPromotionCount() {
return promotionCount;
}
public void setPromotionCount(int promotionCount) {
this.promotionCount = promotionCount;
}
@Override
public String aggName() {
return "recommendPromotionAgg";
}
@Override
public String filterName() {
return "cxfilter";
}
@Override
public AbstractAggregationBuilder<?> getBuilder() {
BoolQueryBuilder boolFilter = QueryBuilders.boolQuery();
Date now = new Date();
boolFilter.must(QueryBuilders.rangeQuery(ProductIndexEsField.matchedPromotionsEndTime).gt(DateUtil.setHourSeonds(now, 1, 0, 0)));
boolFilter.must(QueryBuilders.rangeQuery(ProductIndexEsField.matchedPromotionsStartTime).lt(DateUtil.setHourSeonds(now, 0, 0, 0)));
AbstractAggregationBuilder<NestedAggregationBuilder> nestedAggregationBuilder =
AggregationBuilders.nested(aggName(), ProductIndexEsField.matchedPromotions)
.subAggregation(AggregationBuilders.filter(filterName(), boolFilter)
.subAggregation(AggregationBuilders.terms(TERM_AGGREGATION_NAME).field(ProductIndexEsField.matchedPromotionsId).size(getPromotionCount()).order(Terms.Order.count(false))));
return nestedAggregationBuilder;
}
@Override
public Object getAggregationResponseMap(Map<String, Aggregation> aggMaps) {
InternalNested aggregation = (InternalNested) aggMaps.get(aggName());
if (!CollectionUtils.isEmpty(aggregation.getAggregations().asList())) {
InternalFilter filter = (InternalFilter)aggregation.getAggregations().asList().get(0);
List<LongTerms.Bucket> longTerms = ((LongTerms)filter.getAggregations().asList().get(0)).getBucketsInternal();
List<Integer> ids = longTerms.stream().map(e -> e.getKeyAsNumber().intValue()).collect(Collectors.toList());
if (!CollectionUtils.isEmpty(ids)) {
return promotionIndexBaseService.getPromotionInfosByIds(ISearchConstants.INDEX_NAME_PROMOTIONINDEX, ids);
}
}
return null;
}
}
... ...
... ... @@ -8,17 +8,22 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.PostConstruct;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.get.MultiGetItemResponse;
import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.index.query.QueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;
import com.yoho.error.event.SearchEvent;
import com.yoho.search.base.monitor.PerformanceMonitor;
import com.yoho.search.base.utils.EventReportEnum;
import com.yoho.search.core.es.IElasticsearchClient;
import com.yoho.search.core.es.impl.YohoIndexHelper;
... ... @@ -28,13 +33,21 @@ import com.yoho.search.core.es.model.SearchResult;
@Service
public class SearchCommonService implements ApplicationEventPublisherAware {
private static final Logger ES_PERFORMANCE = LoggerFactory.getLogger("ES_PERFORMANCE");
@Autowired
private ESClientMgr esClientMgr;
@Autowired
private YohoIndexHelper yohoIndexHelper;
private ApplicationEventPublisher publisher;
private PerformanceMonitor performanceMonitor;
@PostConstruct
void init(){
performanceMonitor = new PerformanceMonitor("ES_PERFORMANCE",ES_PERFORMANCE, 10);
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
... ... @@ -65,12 +78,20 @@ public class SearchCommonService implements ApplicationEventPublisherAware {
* @return
*/
public SearchResult doSearch(final String indexName, final SearchParam searchParam) {
IElasticsearchClient client = esClientMgr.getClient(indexName);
SearchResult searchResult = client.search(indexName, indexName, searchParam);
this.publishSearchResultEvent(indexName, searchParam, searchResult);
return searchResult;
long begin = System.currentTimeMillis();
performanceMonitor.addVisitCount();
try {
IElasticsearchClient client = esClientMgr.getClient(indexName);
SearchResult searchResult = client.search(indexName, indexName, searchParam);
this.publishSearchResultEvent(indexName, searchParam, searchResult);
return searchResult;
} catch (Exception e) {
throw e;
}finally{
performanceMonitor.addCost(System.currentTimeMillis() - begin);
}
}
/**
* 根据多个索引查询
*
... ... @@ -79,10 +100,18 @@ public class SearchCommonService implements ApplicationEventPublisherAware {
* @return
*/
public SearchResult doSearch(final List<String> indexNames, final SearchParam searchParam) {
IElasticsearchClient client = esClientMgr.getClient(indexNames.get(0));
SearchResult searchResult = client.search(indexNames, indexNames, searchParam);
this.publishSearchResultEvent(indexNames.toString(), searchParam, searchResult);
return searchResult;
long begin = System.currentTimeMillis();
performanceMonitor.addVisitCount();
try {
IElasticsearchClient client = esClientMgr.getClient(indexNames.get(0));
SearchResult searchResult = client.search(indexNames, indexNames, searchParam);
this.publishSearchResultEvent(indexNames.toString(), searchParam, searchResult);
return searchResult;
} catch (Exception e) {
throw e;
}finally{
performanceMonitor.addCost(System.currentTimeMillis() - begin);
}
}
/**
... ... @@ -93,17 +122,25 @@ public class SearchCommonService implements ApplicationEventPublisherAware {
* @return
*/
public List<SearchResult> doMutiSearch(final String indexName, final List<SearchParam> searchParams) {
if (searchParams == null || searchParams.isEmpty()) {
return new ArrayList<SearchResult>();
}
IElasticsearchClient client = esClientMgr.getClient(indexName);
List<SearchResult> results = client.multiSearch(indexName, indexName, searchParams);
for (int i = 0; i < searchParams.size(); i++) {
SearchResult searchResult = results.get(i);
SearchParam searchParam = searchParams.get(i);
this.publishSearchResultEvent(indexName, searchParam, searchResult);
long begin = System.currentTimeMillis();
performanceMonitor.addVisitCount(searchParams==null?0:searchParams.size());
try {
if (searchParams == null || searchParams.isEmpty()) {
return new ArrayList<SearchResult>();
}
IElasticsearchClient client = esClientMgr.getClient(indexName);
List<SearchResult> results = client.multiSearch(indexName, indexName, searchParams);
for (int i = 0; i < searchParams.size(); i++) {
SearchResult searchResult = results.get(i);
SearchParam searchParam = searchParams.get(i);
this.publishSearchResultEvent(indexName, searchParam, searchResult);
}
return results;
} catch (Exception e) {
throw e;
}finally{
performanceMonitor.addCost(System.currentTimeMillis() - begin);
}
return results;
}
/**
... ... @@ -114,20 +151,28 @@ public class SearchCommonService implements ApplicationEventPublisherAware {
* @return
*/
public Map<String, Object> doGetCommon(final String indexName, final String id) {
if (StringUtils.isBlank(id)) {
return null;
}
IElasticsearchClient client = esClientMgr.getClient(indexName);
List<String> realIndexNames = yohoIndexHelper.getRealIndexNames(indexName, client);
if (realIndexNames == null || realIndexNames.isEmpty()) {
return null;
}
GetResponse response = client.get(realIndexNames.get(0), indexName, id);
// 判断是否为空
if (response == null || response.getSource() == null || response.getSource().isEmpty()) {
return null;
long begin = System.currentTimeMillis();
performanceMonitor.addVisitCount(StringUtils.isBlank(id)?0:1);
try {
if (StringUtils.isBlank(id)) {
return null;
}
IElasticsearchClient client = esClientMgr.getClient(indexName);
List<String> realIndexNames = yohoIndexHelper.getRealIndexNames(indexName, client);
if (realIndexNames == null || realIndexNames.isEmpty()) {
return null;
}
GetResponse response = client.get(realIndexNames.get(0), indexName, id);
// 判断是否为空
if (response == null || response.getSource() == null || response.getSource().isEmpty()) {
return null;
}
return response.getSourceAsMap();
} catch (Exception e) {
throw e;
}finally{
performanceMonitor.addCost(System.currentTimeMillis() - begin);
}
return response.getSourceAsMap();
}
/**
... ... @@ -137,26 +182,34 @@ public class SearchCommonService implements ApplicationEventPublisherAware {
* @return
*/
public List<Map<String, Object>> doMultiGetCommon(final String indexName, final Collection<?> idList) throws Exception {
if (idList == null || idList.isEmpty()) {
return new ArrayList<Map<String, Object>>();
}
IElasticsearchClient client = esClientMgr.getClient(indexName);
List<String> realIndexNames = yohoIndexHelper.getRealIndexNames(indexName, client);
if (realIndexNames == null || realIndexNames.isEmpty()) {
return new ArrayList<Map<String, Object>>();
}
Set<String> idSet = new HashSet<String>();
for (Object id : idList) {
idSet.add(id.toString());
}
MultiGetResponse response = client.multiGet(realIndexNames.get(0), indexName, idSet, null);
List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
for (MultiGetItemResponse item : response.getResponses()) {
if (item.getResponse().isExists()) {
results.add(item.getResponse().getSource());
long begin = System.currentTimeMillis();
performanceMonitor.addVisitCount(idList==null||idList.isEmpty()?0:1);
try {
if (idList == null || idList.isEmpty()) {
return new ArrayList<Map<String, Object>>();
}
IElasticsearchClient client = esClientMgr.getClient(indexName);
List<String> realIndexNames = yohoIndexHelper.getRealIndexNames(indexName, client);
if (realIndexNames == null || realIndexNames.isEmpty()) {
return new ArrayList<Map<String, Object>>();
}
Set<String> idSet = new HashSet<String>();
for (Object id : idList) {
idSet.add(id.toString());
}
MultiGetResponse response = client.multiGet(realIndexNames.get(0), indexName, idSet, null);
List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
for (MultiGetItemResponse item : response.getResponses()) {
if (item.getResponse().isExists()) {
results.add(item.getResponse().getSource());
}
}
return results;
} catch (Exception e) {
throw e;
}finally{
performanceMonitor.addCost(System.currentTimeMillis() - begin);
}
return results;
}
}
... ...
... ... @@ -6,7 +6,7 @@ public class SearchRequestParams {
public static final String PARAM_SEARCH_PAGEID = "pageId"; // 页面id
public static final String PARAM_SEARCH_VIEWNUM = "viewNum"; // 数量
public static final String PARAM_SEARCH_QUERY = "query";// 检索关键词
public static final String PARAM_SEARCH_QUERY = "query";// 检索关键词
public static final String PARAM_SEARCH_SHOPS_KEYWORD = "keyword";// 店铺检索词
public static final String PARAM_SEARCH_GENDER = "gender"; // 性别ids[1,2,3]
... ... @@ -120,4 +120,6 @@ public class SearchRequestParams {
public static final String SHOPS_PARAM_STATUS = "status";
public static final String SHOPS_PARAM_ISGLOBAL = "isGlobal";
public static final String SHOPS_PARAM_CUSTOMIZE_TAG = "customize_tag";
}
... ...
package com.yoho.search.service.base.index;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.service.base.SearchCommonService;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* Created by wangnan on 2017/9/12.
*/
@Service
public class CustomizeTagBaseService {
private final Logger logger = LoggerFactory.getLogger(getClass());
private static final String ACTIVITY_TAG_INDEX_NAME = ISearchConstants.INDEX_NAME_ACTIVITY_TAG;
@Autowired
private SearchCommonService searchCommonService;
public List<Map<String, Object>> getTagListByIds(final Collection<?> tagIds) {
List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
try {
List<Map<String, Object>> sizeEsMapList = searchCommonService.doMultiGetCommon(ACTIVITY_TAG_INDEX_NAME, tagIds);
for (Map<String, Object> sizeEsMap : sizeEsMapList) {
resultList.add(this.getTagMap(sizeEsMap));
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return resultList;
}
private Map<String, Object> getTagMap(Map<String, Object> esMap) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", MapUtils.getIntValue(esMap, "id", 0));
map.put("name", MapUtils.getString(esMap, "activityName", ""));
return map;
}
}
... ...
... ... @@ -9,15 +9,21 @@ import javax.annotation.PostConstruct;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.yoho.search.base.utils.DateUtil;
import com.yoho.search.base.utils.ProductIndexEsField;
@Service
public class ProductIndexBaseService {
private static final Logger logger = LoggerFactory.getLogger(ProductIndexBaseService.class);
@Autowired
private ProductPricePlanIndexBaseService productPricePlanIndexBaseService;
... ... @@ -30,16 +36,16 @@ public class ProductIndexBaseService {
productIndexIncludeFields.add(ProductIndexEsField.productName);
productIndexIncludeFields.add(ProductIndexEsField.productSkn);
productIndexIncludeFields.add(ProductIndexEsField.cnAlphabet);
productIndexIncludeFields.add(ProductIndexEsField.brandId);
productIndexIncludeFields.add(ProductIndexEsField.brandName);
productIndexIncludeFields.add(ProductIndexEsField.brandDomain);
productIndexIncludeFields.add(ProductIndexEsField.countryId);
productIndexIncludeFields.add(ProductIndexEsField.shopId);
productIndexIncludeFields.add(ProductIndexEsField.shopName);
productIndexIncludeFields.add(ProductIndexEsField.shopDomain);
productIndexIncludeFields.add(ProductIndexEsField.salesPrice);
productIndexIncludeFields.add(ProductIndexEsField.marketPrice);
productIndexIncludeFields.add(ProductIndexEsField.vipPrice);
... ... @@ -47,35 +53,33 @@ public class ProductIndexBaseService {
productIndexIncludeFields.add(ProductIndexEsField.vip2Price);
productIndexIncludeFields.add(ProductIndexEsField.vip3Price);
productIndexIncludeFields.add(ProductIndexEsField.vipDiscountType);
productIndexIncludeFields.add(ProductIndexEsField.isStudentPrice);
productIndexIncludeFields.add(ProductIndexEsField.studentPrice);
productIndexIncludeFields.add(ProductIndexEsField.isstudentrebate);
productIndexIncludeFields.add(ProductIndexEsField.defaultImages);
productIndexIncludeFields.add(ProductIndexEsField.sknDefaultImg);
productIndexIncludeFields.add(ProductIndexEsField.editTime);
productIndexIncludeFields.add(ProductIndexEsField.shelveTime);
productIndexIncludeFields.add(ProductIndexEsField.firstShelveTime);
productIndexIncludeFields.add(ProductIndexEsField.maxSortId);
productIndexIncludeFields.add(ProductIndexEsField.middleSortId);
productIndexIncludeFields.add(ProductIndexEsField.smallSortId);
productIndexIncludeFields.add(ProductIndexEsField.smallSort);
productIndexIncludeFields.add(ProductIndexEsField.storageNum);
productIndexIncludeFields.add(ProductIndexEsField.salesNum);
productIndexIncludeFields.add(ProductIndexEsField.gender);
productIndexIncludeFields.add(ProductIndexEsField.ageLevel);
productIndexIncludeFields.add(ProductIndexEsField.salesPhrase);
//productIndexIncludeFields.add(ProductIndexEsField.phrase);
// productIndexIncludeFields.add(ProductIndexEsField.phrase);
productIndexIncludeFields.add(ProductIndexEsField.status);
productIndexIncludeFields.add(ProductIndexEsField.goodsList);
productIndexIncludeFields.add(ProductIndexEsField.isnew);
productIndexIncludeFields.add(ProductIndexEsField.isAdvance);
productIndexIncludeFields.add(ProductIndexEsField.isDepositAdvance);
... ... @@ -87,17 +91,22 @@ public class ProductIndexBaseService {
productIndexIncludeFields.add(ProductIndexEsField.isDiscount);
productIndexIncludeFields.add(ProductIndexEsField.isSoonSoldOut);
productIndexIncludeFields.add(ProductIndexEsField.ispromotion);
productIndexIncludeFields.add(ProductIndexEsField.bundleType);
productIndexIncludeFields.add(ProductIndexEsField.yohoodId);
productIndexIncludeFields.add(ProductIndexEsField.isFobbiden);
productIndexIncludeFields.add(ProductIndexEsField.storeShowStatus);
productIndexIncludeFields.add(ProductIndexEsField.isGlobal);
productIndexIncludeFields.add(ProductIndexEsField.tblBrandId);
productIndexIncludeFields.add(ProductIndexEsField.tblCountryId);
productIndexIncludeFields.add(ProductIndexEsField.tblCountryName);
productIndexIncludeFields.add(ProductIndexEsField.customizeTags);
productIndexIncludeFields.add(ProductIndexEsField.matchedPromotions);
productIndexIncludeFields.add(ProductIndexEsField.basePinRatio);
productIndexIncludeFields.add(ProductIndexEsField.breakingRate);
}
public List<String> getProductIndexIncludeFields() {
... ... @@ -176,6 +185,16 @@ public class ProductIndexBaseService {
productMap.put("is_discount", MapUtils.getString(map, ProductIndexEsField.isDiscount, "N"));
productMap.put("is_soon_sold_out", MapUtils.getString(map, ProductIndexEsField.isSoonSoldOut, "N"));
productMap.put("is_promotion", MapUtils.getIntValue(map, ProductIndexEsField.ispromotion, 0));
productMap.put("is_latest_reduce_price", MapUtils.getString(map, ProductIndexEsField.isLatestReducePrice, "N"));
productMap.put("is_breaking", "N");
if (MapUtils.getDoubleValue(map, ProductIndexEsField.basePinRatio, 0) >= 3.5 && MapUtils.getDoubleValue(map, ProductIndexEsField.breakSizePercent, 0) >= 50) {
productMap.put("is_breaking", "Y");
}
productMap.put("is_promotion_active", "N");
boolean promotionActive = getPromotionActive(map);
if (promotionActive) {
productMap.put("is_promotion_active", "Y");
}
productMap.put("bundle_type", MapUtils.getIntValue(map, ProductIndexEsField.bundleType, 0));
... ... @@ -196,10 +215,44 @@ public class ProductIndexBaseService {
productMap.put("tbl_brand_id", MapUtils.getIntValue(map, ProductIndexEsField.tblBrandId, 0));
productMap.put("tbl_country_name", MapUtils.getString(map, ProductIndexEsField.tblCountryName, ""));
productMap.put("tbl_plane", (tbl_country_id > 0 && tbl_country_id != 86) ? "Y" : "N");
// 标签
productMap.put("customize_tag", MapUtils.getObject(map, ProductIndexEsField.customizeTags, new JSONArray()));
productMap.put("promotion_tag", MapUtils.getObject(map, ProductIndexEsField.matchedPromotions, new JSONArray()));
return productMap;
}
/**
* 判断是否有正在进行的促销
*
* @param map
* @return
*/
private boolean getPromotionActive(Map<String, Object> map) {
try {
long nowUnixTime = DateUtil.getCurrentTimeSecond();
Object matchedPromotions = MapUtils.getObject(map, ProductIndexEsField.matchedPromotions);
if (matchedPromotions == null) {
return false;
}
List<?> matchedPromotionArray = (List<?>)matchedPromotions;
for (int i = 0; i <matchedPromotionArray.size(); i++) {
Map<?,?> matchedPromotion = (Map<?,?>)matchedPromotionArray.get(i);
int startTime = MapUtils.getIntValue(matchedPromotion, "startTime");
int endTime = MapUtils.getIntValue(matchedPromotion, "endTime");
if (startTime < nowUnixTime && nowUnixTime < endTime) {
return true;
}
}
return false;
} catch (Exception e) {
logger.error(e.getMessage(), e);
return false;
}
}
/**
* 获取商品列表[不包含变价计划]
*
* @return
... ... @@ -218,8 +271,8 @@ public class ProductIndexBaseService {
* @return
*/
public List<Map<String, Object>> getProductListWithPricePlan(List<Map<String, Object>> productEsSourceList) {
if(productEsSourceList==null|| productEsSourceList.isEmpty()){
return new ArrayList<Map<String,Object>>();
if (productEsSourceList == null || productEsSourceList.isEmpty()) {
return new ArrayList<Map<String, Object>>();
}
// 获取搜索结果的skn,根据它们来获取product_price_plan
String[] sknStr = new String[productEsSourceList.size()];
... ... @@ -298,4 +351,18 @@ public class ProductIndexBaseService {
return results;
}
public static void main(String[] args) {
Map<String, Object> map = new HashMap<String, Object>();
Map<String, Object> test1 = new HashMap<String, Object>();
test1.put("startTime", 1504195200);
test1.put("id", 10538);
test1.put("endTime", 1533398400);
JSONArray jSONArray = new JSONArray();
jSONArray.add(new HashMap<String, Object>(test1));
map.put("matchedPromotions", jSONArray);
System.out.println(JSON.parseArray(MapUtils.getString(map, ProductIndexEsField.matchedPromotions, "[]")));
}
}
... ...
... ... @@ -43,6 +43,8 @@ class ProductPricePlanIndexBaseService {
productPricePlan.put("effect_time", MapUtils.getIntValue(source, "effectTime"));
productPricePlan.put("end_time", MapUtils.getIntValue(source, "endTime"));
productPricePlan.put("vip_discount", MapUtils.getDoubleValue(source, "vipDiscount"));
productPricePlan.put("show_status", MapUtils.getIntValue(source, "showStatus"));
productPricePlan.put("show_begin_time", MapUtils.getIntValue(source, "showBeginTime"));
return productPricePlan;
}
... ...
package com.yoho.search.service.base.index;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.yoho.search.base.utils.ConvertUtils;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import com.yoho.search.models.RecommendPromotionAggVO;
import com.yoho.search.service.base.SearchCommonService;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
... ... @@ -13,12 +15,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import com.yoho.search.base.utils.ConvertUtils;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import com.yoho.search.service.base.SearchCommonService;
import java.util.*;
/**
* Created by wangnan on 2017/5/11.
... ... @@ -51,6 +50,29 @@ public class PromotionIndexBaseService {
}
}
public List<RecommendPromotionAggVO> getPromotionInfosByIds(String indexName, List<Integer> ids){
SearchParam searchParam = new SearchParam();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.termsQuery(ProductIndexEsField.id, ids));
boolQueryBuilder.must(QueryBuilders.termQuery(ProductIndexEsField.status, 1));
boolQueryBuilder.mustNot(QueryBuilders.termQuery(ProductIndexEsField.isDel, "Y"));
boolQueryBuilder.mustNot(QueryBuilders.termQuery(ProductIndexEsField.commonBanner, ""));
searchParam.setFiter(boolQueryBuilder);
searchParam.setSize(ids.size());
SearchResult searchResult = searchCommonService.doSearch(indexName, searchParam);
if (searchResult == null || CollectionUtils.isEmpty(searchResult.getResultList())) {
return Collections.emptyList();
}
List<RecommendPromotionAggVO> resultList = new ArrayList<>();
for (Map<String, Object> esMap : searchResult.getResultList()) {
if (!CollectionUtils.isEmpty(esMap)) {
resultList.add(parsePromotionInfos(esMap));
}
}
return resultList;
}
private List<Map<String, Object>> queryListByParam(SearchParam searchParam) {
List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
SearchResult searchResult = searchCommonService.doSearch(INDEX_NAME, searchParam);
... ... @@ -71,8 +93,8 @@ public class PromotionIndexBaseService {
}
return boolFilter;
}
public Map<String, Object> getMap(Map<String, Object> esMap) {
private Map<String, Object> getMap(Map<String, Object> esMap) {
Map<String, Object> map = new HashMap<>();
int id = MapUtils.getIntValue(esMap, "id", 0);
map.put("is_promotion", id + "");
... ... @@ -80,4 +102,12 @@ public class PromotionIndexBaseService {
return map;
}
private RecommendPromotionAggVO parsePromotionInfos(Map<String, Object> esMap) {
RecommendPromotionAggVO recommendPromotionAggVO = new RecommendPromotionAggVO();
recommendPromotionAggVO.setPromotionInfoId(MapUtils.getIntValue(esMap, "id", 0));
recommendPromotionAggVO.setTitle(MapUtils.getString(esMap,"title", ""));
recommendPromotionAggVO.setCoverImgUrl(MapUtils.getString(esMap, "commonBanner", ""));
return recommendPromotionAggVO;
}
}
... ...
package com.yoho.search.service.helper;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.yoho.search.base.utils.*;
import com.yoho.search.service.base.SearchDynamicConfigService;
import com.yoho.search.service.base.SearchRequestParams;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
... ... @@ -11,11 +10,9 @@ import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.yoho.search.base.utils.CharUtils;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.base.utils.SearchPageIdDefine;
import com.yoho.search.service.base.SearchDynamicConfigService;
import com.yoho.search.service.base.SearchRequestParams;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Component
public class SearchCommonHelper {
... ... @@ -368,4 +365,19 @@ public class SearchCommonHelper {
return null;
}
/**
* 自定义标签过滤
* @param paramMap
* @return
*/
public BoolQueryBuilder getCustomizeTagBuilder(Map<String, String> paramMap) {
if (paramMap.containsKey(SearchRequestParams.SHOPS_PARAM_CUSTOMIZE_TAG) && StringUtils.isNotBlank(SearchRequestParams.SHOPS_PARAM_CUSTOMIZE_TAG)) {
int[] ids = ConvertUtils.stringToIntArray(paramMap.get(SearchRequestParams.SHOPS_PARAM_CUSTOMIZE_TAG), ",");
BoolQueryBuilder nestedBoolFilter = QueryBuilders.boolQuery();
nestedBoolFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.customizeTagsId, ids));
return nestedBoolFilter;
}
return null;
}
}
... ...
package com.yoho.search.service.helper;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yoho.search.base.constants.ProductModelValueConstants;
import com.yoho.search.base.utils.ConvertUtils;
import com.yoho.search.base.utils.DateUtil;
... ... @@ -26,6 +7,15 @@ import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.common.utils.SearchKeyWordUtils;
import com.yoho.search.service.base.SearchRequestParams;
import org.apache.commons.lang.StringUtils;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.index.query.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
@Service
public class SearchServiceHelper {
... ... @@ -224,6 +214,7 @@ public class SearchServiceHelper {
int[] storeShowStatuss = ConvertUtils.stringToIntArray(paramMap.get(SearchRequestParams.PARAM_SEARCH_STORESHOWSTATUS), ",");
boolFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.storeShowStatus, storeShowStatuss));
}
// //////////////////////////////////////////不支持多个参数///////////////////////////////////////////////////////////
// 是否特价
if (this.checkParamNotFiltered(paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_SPECIALOFFER)) {
... ... @@ -457,6 +448,13 @@ public class SearchServiceHelper {
boolFilter.must(QueryBuilders.nestedQuery(ProductIndexEsField.activities, activitiesTermsBuilder,ScoreMode.None));
}
//自定义标签
BoolQueryBuilder customizeTagsTermsBuilder = searchCommonHelper.getCustomizeTagBuilder(paramMap);
if (customizeTagsTermsBuilder != null) {
boolFilter.must(QueryBuilders.nestedQuery(ProductIndexEsField.customizeTags, customizeTagsTermsBuilder,ScoreMode.None));
}
// 如果contain_seckill!=Y,则过滤掉秒杀商品
if (!paramMap.containsKey(SearchRequestParams.PARAM_SEARCH_CONTAIN_SECKILL) || !"Y".equals(paramMap.get(SearchRequestParams.PARAM_SEARCH_CONTAIN_SECKILL))) {
boolFilter.mustNot(QueryBuilders.termsQuery(ProductIndexEsField.isSeckill, "Y"));
... ... @@ -486,7 +484,9 @@ public class SearchServiceHelper {
if (this.checkParamNotFiltered(paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_NOT_SHOP_ID)) {
boolFilter.mustNot(QueryBuilders.termsQuery(ProductIndexEsField.shopId, paramMap.get(SearchRequestParams.PARAM_SEARCH_NOT_SHOP_ID).split(",")));
}
// // 通用的过滤请求
// for (String key : paramMap.keySet()) {
// if (key.startsWith("not_")) {
... ...
... ... @@ -114,7 +114,7 @@ public class BreakSizeSceneService extends AbstractSceneService {
this.addParamsToParamMap(paramMap);
// 2、返回聚合结果
List<IAggregation> aggregation = sceneSelectionsService.getBreakSizeAggregations(paramMap);
return sceneSelectionsService.aggregations(paramMap, aggregation);
return sceneSelectionsService.aggregations(paramMap, aggregation,true);
} catch (Exception e) {
logger.error("[func=Couponaggregations][params=" + paramMap + "]", e);
return SearchApiResultUtils.errorSearchApiResult("Couponaggregations", paramMap, e);
... ...
package com.yoho.search.service.scene;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.base.utils.SearchPageIdDefine;
import com.yoho.search.common.utils.SearchApiResultUtils;
... ... @@ -19,7 +11,21 @@ import com.yoho.search.service.helper.SearchKeyWordHelper;
import com.yoho.search.service.scene.common.AbstractSceneService;
import com.yoho.search.service.scene.common.SceneProductListService;
import com.yoho.search.service.scene.common.SceneSelectionsService;
import com.yoho.search.service.service.IAggRecommendService;
import com.yoho.search.service.service.IProductIndexService;
import com.yoho.search.service.service.ISearchRecommendService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Service
public class FuzzySceneService extends AbstractSceneService {
... ... @@ -38,6 +44,12 @@ public class FuzzySceneService extends AbstractSceneService {
private SearchDynamicConfigService searchDynamicConfigService;
@Autowired
private SearchKeyWordHelper searchKeyWordService;
@Autowired
private IProductIndexService productIndexService;
@Autowired
private IAggRecommendService aggRecommendService;
private ExecutorService executorService = Executors.newFixedThreadPool(100);
// 当少于20个商品时 返回智能搜索词提示
private static final int SMART_SUGGESTION_PRODUCT_LIMIT = 20;
... ... @@ -62,22 +74,35 @@ public class FuzzySceneService extends AbstractSceneService {
@Override
public SearchApiResult productList(Map<String, String> paramMap) {
try {
// 0、参数校验
// 1、参数校验
if (StringUtils.isBlank(paramMap.get(SearchRequestParams.PARAM_SEARCH_QUERY))) {
return new SearchApiResult().setCode(400).setMessage("请传query参数");
}
// 1、添加默认参数
// 2、添加默认参数
this.addParamsToParamMap(paramMap);
// 2、获取商品列表
// 3、获取商品列表
SearchApiResult searchApiResult = sceneProductListService.productList(paramMap);
// 3、加入建议词
// 4、加入建议词
this.addSuggestion(searchApiResult, paramMap);
// 4、模糊搜索页记录关键字对应的查询结果
// 5、模糊搜索页记录关键字对应的查询结果
String queryWord = paramMap.get("query");
if (!StringUtils.isBlank(queryWord) && !searchCommonHelper.isQuerySknOrSku(queryWord)) {
long total = ((JSONObject) searchApiResult.getData()).getLongValue("total");
searchKeyWordService.recordKeyWordByResultCount(queryWord, total);
}
ConcurrentHashMap<String, String> syncParamMap = new ConcurrentHashMap<>(paramMap);
// 6、获取自定义标签聚合结果
CompletableFuture<SearchApiResult> customizeTagFuture = CompletableFuture.supplyAsync(() -> productIndexService.aggCustomizeTag(syncParamMap), executorService);
CompletableFuture<List<Object>> recommendProductFuture = CompletableFuture.supplyAsync(() -> aggRecommendService.recommendPromotion(syncParamMap), executorService);
SearchApiResult customizeTags = customizeTagFuture.get();
List<Object> recommendProducts = recommendProductFuture.get();
JSONObject dataMap = (JSONObject)searchApiResult.getData();
dataMap.put(CUSTOMIZE_TAG_LIST, customizeTags.getData());
dataMap.put(RECOMMEND_PROMOTION_LIST, recommendProducts);
return searchApiResult;
} catch (Exception e) {
logger.error(e.getMessage(), e);
... ...
package com.yoho.search.service.scene;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
... ... @@ -7,9 +9,12 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yoho.search.base.utils.DateUtil;
import com.yoho.search.base.utils.SearchPageIdDefine;
import com.yoho.search.common.utils.SearchApiResultUtils;
import com.yoho.search.core.es.agg.IAggregation;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.base.SearchRequestParams;
import com.yoho.search.service.scene.common.AbstractSceneService;
import com.yoho.search.service.scene.common.SceneProductListService;
import com.yoho.search.service.scene.common.SceneSelectionsService;
... ... @@ -32,8 +37,12 @@ public class NewArrivalSceneService extends AbstractSceneService {
@Override
public void addParamsToParamMap(Map<String, String> paramMap) {
super.addDefaultParamsToParamMap(paramMap);
// 默认30天内假上新
long end = DateUtil.getLastTimeSecond(new Date());
long begin = DateUtil.getFirstTimeSecond(DateUtil.addDay(new Date(), -30));
paramMap.put(SearchRequestParams.PARAM_SEARCH_SHELVETIME, begin + "," + end);
}
@Override
public SearchApiResult productList(Map<String, String> paramMap) {
try {
... ... @@ -60,4 +69,17 @@ public class NewArrivalSceneService extends AbstractSceneService {
}
}
public SearchApiResult oldAggregations(Map<String, String> paramMap) {
try {
// 1、添加默认参数
this.addParamsToParamMap(paramMap);
// 2、返回聚合结果
List<IAggregation> aggregations = sceneSelectionsService.getNewArrivalOldAggregations(paramMap);
return sceneSelectionsService.aggregations(paramMap, aggregations, false);
} catch (Exception e) {
logger.error("[func=ShopAggregations][params=" + paramMap + "]", e);
return SearchApiResultUtils.errorSearchApiResult("ShopAggregations", paramMap, e);
}
}
}
... ...
package com.yoho.search.service.scene;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yoho.search.base.utils.DateUtil;
import com.yoho.search.base.utils.SearchPageIdDefine;
import com.yoho.search.common.utils.SearchApiResultUtils;
import com.yoho.search.core.es.agg.IAggregation;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.base.SearchRequestParams;
import com.yoho.search.service.scene.common.AbstractSceneService;
import com.yoho.search.service.scene.common.SceneProductListService;
import com.yoho.search.service.scene.common.SceneSelectionsService;
@Service
public class ReducePriceSceneService extends AbstractSceneService {
private static final Logger logger = LoggerFactory.getLogger(ReducePriceSceneService.class);
@Autowired
private SceneProductListService sceneProductListService;
@Autowired
private SceneSelectionsService sceneSelectionsService;
@Override
public String pageId() {
return SearchPageIdDefine.PAGE_ID_REDUCE_PRICE;
}
@Override
public void addParamsToParamMap(Map<String, String> paramMap) {
super.addDefaultParamsToParamMap(paramMap);
// 默认打折
paramMap.put(SearchRequestParams.PARAM_SEARCH_ISDISCOUNT, "Y");
// 默认一周降价
long end = DateUtil.getLastTimeSecond(new Date());
long begin = DateUtil.getFirstTimeSecond(DateUtil.addDay(new Date(), -7));
paramMap.put(SearchRequestParams.PARAM_SEARCH_PRICE_UPDATE_TIME, begin + "," + end);
}
@Override
public SearchApiResult productList(Map<String, String> paramMap) {
try {
// 1、添加默认参数
this.addParamsToParamMap(paramMap);
// 2、返回商品列表
return sceneProductListService.productList(paramMap);
} catch (Exception e) {
logger.error("[func=NewArrivalProductList][params=" + paramMap + "]", e);
return SearchApiResultUtils.errorSearchApiResult("NewArrivalProductList", paramMap, e);
}
}
@Override
public SearchApiResult aggregations(Map<String, String> paramMap) {
try {
// 1、添加默认参数
this.addParamsToParamMap(paramMap);
// 2、返回聚合结果
List<IAggregation> aggregation = sceneSelectionsService.getReducePriceAggregations(paramMap);
return sceneSelectionsService.aggregations(paramMap, aggregation,false);
} catch (Exception e) {
logger.error("[func=NewArrivalAggregations][params=" + paramMap + "]", e);
return SearchApiResultUtils.errorSearchApiResult("NewArrivalAggregations", paramMap, e);
}
}
}
... ...
package com.yoho.search.service.scene;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
... ... @@ -10,6 +11,7 @@ import org.springframework.stereotype.Service;
import com.yoho.search.base.utils.SearchPageIdDefine;
import com.yoho.search.common.utils.SearchApiResultUtils;
import com.yoho.search.core.es.agg.IAggregation;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.base.SearchRequestParams;
import com.yoho.search.service.scene.common.AbstractSceneService;
... ... @@ -69,4 +71,21 @@ public class ShopSceneService extends AbstractSceneService {
return SearchApiResultUtils.errorSearchApiResult("ShopAggregations", paramMap, e);
}
}
public SearchApiResult oldAggregations(Map<String, String> paramMap) {
try {
// 0、参数校验
if (StringUtils.isBlank(paramMap.get(SearchRequestParams.PARAM_SEARCH_SHOP))) {
return new SearchApiResult().setCode(400).setMessage("请传shop参数");
}
// 1、添加默认参数
this.addParamsToParamMap(paramMap);
// 2、返回聚合结果
List<IAggregation> aggregations = sceneSelectionsService.getShopOldAggregations(paramMap);
return sceneSelectionsService.aggregations(paramMap, aggregations,false);
} catch (Exception e) {
logger.error("[func=ShopAggregations][params=" + paramMap + "]", e);
return SearchApiResultUtils.errorSearchApiResult("ShopAggregations", paramMap, e);
}
}
}
... ...
package com.yoho.search.service.scene;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.base.utils.SearchPageIdDefine;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.aggregations.impls.AggregationFactoryService;
import com.yoho.search.service.base.SearchRequestParams;
import com.yoho.search.service.helper.SearchCommonHelper;
import com.yoho.search.service.scene.common.AbstractSceneService;
import com.yoho.search.service.scene.common.SceneProductListService;
import com.yoho.search.service.scene.common.SceneSelectionsService;
import com.yoho.search.service.service.IAggRecommendService;
import com.yoho.search.service.service.IProductIndexService;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Service
public class SortSceneService extends AbstractSceneService {
... ... @@ -40,7 +40,7 @@ public class SortSceneService extends AbstractSceneService {
@Autowired
private IProductIndexService productIndexService;
@Autowired
private AggregationFactoryService aggregationFactoryService;
private IAggRecommendService aggRecommendService;
@Override
public String pageId() {
... ... @@ -85,24 +85,32 @@ public class SortSceneService extends AbstractSceneService {
}
// 1、添加默认参数
this.addParamsToParamMap(paramMap);
ConcurrentHashMap<String, String> syncParamMap = new ConcurrentHashMap<>(paramMap);
// 2、获取商品列表
CompletableFuture<SearchApiResult> productListFuture = CompletableFuture.supplyAsync(() -> {
try {
return sceneProductListService.productList(paramMap);
return sceneProductListService.productList(syncParamMap);
} catch (Exception e) {
logger.error(e.getMessage(), e);
return null;
}
}, executorService);
// 3、获取规则的聚合结果
CompletableFuture<SearchApiResult> standardsFuture = CompletableFuture.supplyAsync(() -> {
return productIndexService.aggStandard(paramMap);
}, executorService);
// 3、获取规则和自定义标签的聚合结果
CompletableFuture<SearchApiResult> standardsFuture = CompletableFuture.supplyAsync(() -> productIndexService.aggStandard(syncParamMap), executorService);
CompletableFuture<SearchApiResult> customizeTagFuture = CompletableFuture.supplyAsync(() -> productIndexService.aggCustomizeTag(syncParamMap), executorService);
CompletableFuture<List<Object>> recommendProductFuture = CompletableFuture.supplyAsync(() -> aggRecommendService.recommendPromotion(syncParamMap), executorService);
// 4、组合结果
SearchApiResult productList = productListFuture.get();
SearchApiResult standards = standardsFuture.get();
SearchApiResult customizeTags = customizeTagFuture.get();
List<Object> recommendProducts = recommendProductFuture.get();
JSONObject jsonObject = (JSONObject) productList.getData();
jsonObject.put("standard", standards.getData());
jsonObject.put(CUSTOMIZE_TAG_LIST, customizeTags.getData());
jsonObject.put(RECOMMEND_PROMOTION_LIST, recommendProducts);
return productList;
} catch (Exception e) {
logger.error(e.getMessage(), e);
... ...
package com.yoho.search.service.scene.common;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.base.SearchRequestParams;
import org.apache.commons.lang.StringUtils;
import java.util.Map;
public abstract class AbstractSceneService {
protected static final String RECOMMEND_PROMOTION_LIST = "recommend_promotion_list";
protected static final String CUSTOMIZE_TAG_LIST = "customize_tag";
/**
* 场景化的默认参数
*
... ... @@ -26,7 +28,7 @@ public abstract class AbstractSceneService {
paramMap.put(SearchRequestParams.PARAM_SEARCH_AGG_WITH_PARAM_BRAND, "Y");// 聚合时使用参数中自带的参数
// paramMap.put("sale", "Y");// 没用的参数
}
protected int getPage(Map<String, String> paramMap) {
int page = StringUtils.isBlank(paramMap.get("page")) ? 1 : Integer.parseInt(paramMap.get("page"));
return page;
... ...
... ... @@ -44,7 +44,6 @@ public class SceneSelectionsService extends AbstractCacheAbleService {
@Autowired
private IAggRecommendService aggRecommendService;
@Override
public SearchCache getSearchCache() {
return searchCacheFactory.getSelectionsForAppCache();
... ... @@ -122,20 +121,46 @@ public class SceneSelectionsService extends AbstractCacheAbleService {
}
/**
* 店铺、新频到着的筛选项列表
* 最新降价的筛选项
*
* @param paramMap
* @return
*/
@SuppressWarnings("unused")
private List<IAggregation> getRNAggregations(Map<String, String> paramMap) {
public List<IAggregation> getReducePriceAggregations(Map<String, String> paramMap) {
List<IAggregation> aggregations = new ArrayList<>();
// 1)性别
aggregations.add(aggregationFactoryService.getGenderNewAggregation());
// 2)品类
// 2)品牌
aggregations.add(aggregationFactoryService.getBrandAggregation(paramMap));
// 3)品类
aggregations.add(aggregationFactoryService.getSortGroupAggregation(paramMap));
// 3)品牌
// 4)颜色
aggregations.add(aggregationFactoryService.getColorAggregation(paramMap));
// 5)尺码
aggregations.add(aggregationFactoryService.getSizeAggregation());
// 6)价格
aggregations.add(aggregationFactoryService.getPriceAggregation());
// 7)折扣
aggregations.add(aggregationFactoryService.getDiscountAggregation());
// 8)风格
aggregations.add(aggregationFactoryService.getStyleAggregation(paramMap));
return aggregations;
}
/**
* 老的店铺的筛选项
*
* @param paramMap
* @return
*/
public List<IAggregation> getShopOldAggregations(Map<String, String> paramMap) {
List<IAggregation> aggregations = new ArrayList<>();
// 1)性别
aggregations.add(aggregationFactoryService.getGenderNewAggregation());
// 2)品牌
aggregations.add(aggregationFactoryService.getBrandAggregation(paramMap));
// 3)品类
aggregations.add(aggregationFactoryService.getSortGroupAggregation(paramMap));
// 4)颜色
aggregations.add(aggregationFactoryService.getColorAggregation(paramMap));
// 5)尺码
... ... @@ -144,6 +169,35 @@ public class SceneSelectionsService extends AbstractCacheAbleService {
aggregations.add(aggregationFactoryService.getPriceAggregation());
// 7)折扣
aggregations.add(aggregationFactoryService.getDiscountAggregation());
// 8)风格
aggregations.add(aggregationFactoryService.getStyleAggregation(paramMap));
return aggregations;
}
/**
* 老的新品到着的筛选项
*
* @param paramMap
* @return
*/
public List<IAggregation> getNewArrivalOldAggregations(Map<String, String> paramMap) {
List<IAggregation> aggregations = new ArrayList<>();
// 1)性别
aggregations.add(aggregationFactoryService.getGenderNewAggregation());
// 2)品牌
aggregations.add(aggregationFactoryService.getBrandAggregation(paramMap));
// 3)品类
aggregations.add(aggregationFactoryService.getSortGroupAggregation(paramMap));
// 4)颜色
aggregations.add(aggregationFactoryService.getColorAggregation(paramMap));
// 5)尺码
aggregations.add(aggregationFactoryService.getSizeAggregation());
// 6)价格
aggregations.add(aggregationFactoryService.getPriceAggregation());
// 7)折扣
aggregations.add(aggregationFactoryService.getDiscountAggregation());
// 8)风格
aggregations.add(aggregationFactoryService.getStyleAggregation(paramMap));
return aggregations;
}
... ... @@ -209,41 +263,47 @@ public class SceneSelectionsService extends AbstractCacheAbleService {
return new JSONObject();
}
}
private JSONArray getRecommendBrands(Map<String, String> paramMap, BoolQueryBuilder mustFilter) {
Map<String, String> newParamMap = new HashMap<String, String>(paramMap);
SearchApiResult searchApiResult = aggRecommendService.aggRecommendBrand(newParamMap, mustFilter);
return (JSONArray) searchApiResult.getData();
}
public SearchApiResult aggregations(Map<String, String> paramMap) throws Exception {
List<IAggregation> commonAggregations = this.getCommonAggregations(paramMap);
return this.aggregations(paramMap, commonAggregations, null);
}
public SearchApiResult aggregations(Map<String, String> paramMap, List<IAggregation> aggregations) throws Exception {
return this.aggregations(paramMap, aggregations, null);
public SearchApiResult aggregations(Map<String, String> paramMap, List<IAggregation> aggregations, boolean needRecommendBrand) throws Exception {
return this.aggregations(paramMap, aggregations, null,needRecommendBrand);
}
public SearchApiResult aggregations(Map<String, String> paramMap, BoolQueryBuilder mustFilter) throws Exception {
List<IAggregation> commonAggregations = this.getCommonAggregations(paramMap);
return this.aggregations(paramMap, commonAggregations, mustFilter);
}
public SearchApiResult aggregations(Map<String, String> paramMap, List<IAggregation> aggregations, BoolQueryBuilder mustFilter) throws Exception {
return this.aggregations(paramMap,aggregations,mustFilter,true);
}
public SearchApiResult aggregations(Map<String, String> paramMap, List<IAggregation> aggregations, BoolQueryBuilder mustFilter,boolean needRecommendBrand) throws Exception {
// 1、获取通用筛选项
CompletableFuture<JSONObject> commonFiltersFuture = CompletableFuture.supplyAsync(() -> {
return this.getFiltersResult(paramMap, aggregations, mustFilter);
}, executorService);
// 2、获取推荐的品牌
CompletableFuture<Object> recommendBrandFuture = CompletableFuture.supplyAsync(() -> {
return this.getRecommendBrands(paramMap, mustFilter);
}, executorService);
CompletableFuture<Object> recommendBrandFuture = null;
if(needRecommendBrand){
recommendBrandFuture = CompletableFuture.supplyAsync(() -> {
return this.getRecommendBrands(paramMap, mustFilter);
}, executorService);
}
// 3、组合
JSONObject commonFilters = commonFiltersFuture.get();
Object recommendBrand = recommendBrandFuture.get();
if (recommendBrand != null) {
commonFilters.put("recommendBrand", recommendBrand);
if (needRecommendBrand && recommendBrandFuture != null) {
commonFilters.put("recommendBrand", recommendBrandFuture.get());
}
// 4、返回最终结果
Map<String, Object> result = new JSONObject();
... ...
... ... @@ -22,8 +22,6 @@ import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.common.cache.SearchCacheFactory;
import com.yoho.search.common.cache.model.SearchCache;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import com.yoho.search.models.SearchFieldBoost;
... ... @@ -61,14 +59,9 @@ public class SearchLikeHelper {
@Autowired
private SearchCacheService searchCacheService;
@Autowired
private SearchCacheFactory searchCacheFactory;
private SearchCache searchLikeSearchCache;
@PostConstruct
void init() {
searchLikeSearchCache = searchCacheFactory.getSearchLikeSearchCache();
// 品类权重
List<String> searchFields = Arrays.asList("smallSort", "smallSort.smallSort_pinyin", "middleSort", "middleSort.middleSort_pinyin", "maxSort", "maxSort.maxSort_pinyin");
this.addSearchFieldBoost(searchFields, sortMaxBoost);
... ...
package com.yoho.search.service.service;
import java.util.Arrays;
import java.util.Map;
import javax.annotation.PostConstruct;
import org.elasticsearch.search.aggregations.Aggregation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSONObject;
import com.yoho.error.event.SearchEvent;
import com.yoho.search.base.utils.EventReportEnum;
... ... @@ -28,6 +15,17 @@ import com.yoho.search.service.base.SearchCacheService;
import com.yoho.search.service.base.SearchCommonService;
import com.yoho.search.service.base.SearchRequestParams;
import com.yoho.search.service.helper.SearchParamHelper;
import org.elasticsearch.search.aggregations.Aggregation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.Map;
@Service
public class AggregationService implements ApplicationEventPublisherAware {
... ... @@ -262,4 +260,14 @@ public class AggregationService implements ApplicationEventPublisherAware {
return this.getAggNameAndResponseWithCache(standardAggregation, searchParam);
}
/**
* 获取自定义标签的聚合结果
*/
public JSONObject getCustomizeTagResult(Map<String, String> paramMap) throws Exception {
IAggregation customizeAggregation = aggregationFactoryService.getCustomizeTagAggregation(paramMap);
String filterParamName = null;
SearchParam searchParam = this.genSearchParamForAgg(customizeAggregation, paramMap, filterParamName, 0);
return this.getAggNameAndResponseWithCache(customizeAggregation, searchParam);
}
}
... ...
package com.yoho.search.service.service;
import java.util.List;
import java.util.Map;
import org.elasticsearch.index.query.BoolQueryBuilder;
... ... @@ -14,7 +15,7 @@ public interface IAggRecommendService {
* @param paramMap
* @return
*/
public SearchApiResult aggRecommendBrand(Map<String, String> paramMap);
SearchApiResult aggRecommendBrand(Map<String, String> paramMap);
/**
* 获取品牌的聚合结果[使用本地缓存]
... ... @@ -22,7 +23,7 @@ public interface IAggRecommendService {
* @param paramMap
* @return
*/
public SearchApiResult aggRecommendBrand(Map<String, String> paramMap, BoolQueryBuilder mustFilter);
SearchApiResult aggRecommendBrand(Map<String, String> paramMap, BoolQueryBuilder mustFilter);
/**
... ... @@ -31,6 +32,13 @@ public interface IAggRecommendService {
* @param paramMap
* @return
*/
public SearchApiResult aggRecommendShop(Map<String, String> paramMap);
SearchApiResult aggRecommendShop(Map<String, String> paramMap);
/**
* 获取促销的聚合结果[使用本地缓存]
*
* @return
*/
List<Object> recommendPromotion(Map<String, String> paramMap);
}
... ...
... ... @@ -8,75 +8,75 @@ public interface IProductIndexService {
/**
* 获取年龄层面的聚合结果
*
*
* @param paramMap
* @return
*/
public SearchApiResult aggAgeLevel(Map<String, String> paramMap);
/**
* 获取性别层面的聚合结果
* @param paramMap
* @return
*/
public SearchApiResult aggGender(Map<String, String> paramMap);
/**
* 获取价格层面的聚合结果
* @param paramMap
* @return
*/
public SearchApiResult aggPrice(Map<String, String> paramMap);
/**
* 获取颜色层面的聚合结果
* @param paramMap
* @return
*/
public SearchApiResult aggColor(Map<String, String> paramMap);
/**
* 获取风格层面的聚合结果
* @param paramMap
* @return
*/
public SearchApiResult aggStyle(Map<String, String> paramMap);
/**
* 获取品牌的聚合结果
* @param paramMap
* @return
*/
public SearchApiResult aggBrand(Map<String, String> paramMap);
/**
* 获取标准的聚合结果
* @param paramMap
* @return
*/
public SearchApiResult aggStandard(Map<String, String> paramMap);
/**
* 获取尺码的聚合结果
* @param paramMap
* @return
*/
public SearchApiResult aggSize(Map<String, String> paramMap);
/**
* 是否新品的聚合结果
* @param paramMap
* @return
*/
public SearchApiResult aggNew(Map<String, String> paramMap);
/**
* 是否限量的聚合结果
* @param paramMap
* @return
*/
public SearchApiResult aggLimited(Map<String, String> paramMap);
/**
* 是否促销的聚合结果
* @param paramMap
... ... @@ -99,5 +99,18 @@ public interface IProductIndexService {
*/
SearchApiResult aggKeywords(Map<String, String> paramMap);
/**
* 店铺
* @param paramMap
* @return
*/
SearchApiResult aggShops(Map<String, String> paramMap);
/**
* 自定义标签
* @param paramMap
* @return
*/
SearchApiResult aggCustomizeTag(Map<String, String> paramMap);
}
... ...
... ... @@ -2,6 +2,7 @@ package com.yoho.search.service.service.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
... ... @@ -36,6 +37,7 @@ import com.yoho.search.service.service.IAggRecommendService;
public class AggRecommendServiceImpl implements IAggRecommendService {
private static final Logger logger = LoggerFactory.getLogger(AggRecommendServiceImpl.class);
private static final int DEFAULT_AGGREGATION_COUNT = 100;
@Autowired
private AggregationService aggregationService;
... ... @@ -132,7 +134,7 @@ public class AggRecommendServiceImpl implements IAggRecommendService {
searchParam.setAggregationBuilders(Arrays.asList(recommendShopAgg.getBuilder()));
// 4、构建offset
searchParam.setOffset(100);// justForCache
searchParam.setOffset(DEFAULT_AGGREGATION_COUNT);// justForCache
// 5、从缓存中获取
final String productIndexName = ISearchConstants.INDEX_NAME_PRODUCT_INDEX;
... ... @@ -158,6 +160,64 @@ public class AggRecommendServiceImpl implements IAggRecommendService {
}
}
@Override
public List<Object> recommendPromotion(Map<String, String> paramMap) {
try {
// 1、获取核心参数
int page = StringUtils.isBlank(paramMap.get("page")) ? 1 : Integer.parseInt(paramMap.get("page"));
// 1.1添加默认参数
paramMap.remove(SearchRequestParams.PARAM_SEARCH_ORDER);// 此接口不支持order
paramMap.put(SearchRequestParams.PARAM_SEARCH_GLOBAL_FILTER_BRAND, "Y");// 页面屏蔽
paramMap.put(SearchRequestParams.PARAM_SEARCH_STATUS, "1");// 上架
paramMap.put(SearchRequestParams.PARAM_SEARCH_STOCKNUM, "1");// 有库存
paramMap.put(SearchRequestParams.PARAM_SEARCH_ISOUTLETS, "2");// 非奥莱
paramMap.put(SearchRequestParams.PARAM_SEARCH_ATTRIBUTE_NOT, "2");// 非赠品
// 2、构建带queryBuilder和filter的SearchParam
SearchParam searchParam = searchParamHelper.buildWithPersional(paramMap, false);
// 3、构造聚合操作
IAggregation recommendPromotionAgg = aggregationFactoryService.getRecommendPromotionAggregation(DEFAULT_AGGREGATION_COUNT);
searchParam.setAggregationBuilders(Arrays.asList(recommendPromotionAgg.getBuilder()));
// 4、构建offset
searchParam.setOffset(DEFAULT_AGGREGATION_COUNT);// justForCache
// 5、从缓存中获取
JSONArray cacheJSONArray = searchCacheService.getJSONArrayFromCache(searchCache, ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParam);
if (cacheJSONArray != null) {
SearchCacheMatchLogger.doSearchCacheMatchLog("/productList.json", paramMap);
return subList(cacheJSONArray, page, 1);
}
// 6、从ES中获取
JSONObject recommendPromotionResult = aggregationService.getAggNameAndResponse(recommendPromotionAgg, searchParam);
if (recommendPromotionResult == null) {
return Collections.emptyList();
}
// 7、生成结果并且加入缓存
JSONArray recommendPromotions = recommendPromotionResult.getJSONArray(recommendPromotionAgg.aggName());
if (recommendPromotions != null) {
searchCacheService.addJSONArrayToCache(searchCache, ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParam, recommendPromotions);
return subList(recommendPromotions, page, 1);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
return Collections.emptyList();
}
return Collections.emptyList();
}
private List<Object> subList(JSONArray sourceList, int page, int count) {
if (sourceList != null && !sourceList.isEmpty()) {
int start = (page - 1) * count;
int end = start + count;
if (start >= sourceList.size()) {
return Collections.emptyList();
}
if (end > sourceList.size()) {
end = sourceList.size();
}
return sourceList.subList(start, end);
}
return Collections.emptyList();
}
private SearchApiResult getRecommendShopSearchApiResult(JSONArray cacheJSONArray, int page, int count) {
List<Map<String, Object>> cacheList = new ArrayList<Map<String, Object>>();
for (int i = 0; i < cacheJSONArray.size(); i++) {
... ... @@ -166,5 +226,5 @@ public class AggRecommendServiceImpl implements IAggRecommendService {
List<Map<String, Object>> results = CollectionUtils.memoryPaging(cacheList, page, count);
return new SearchApiResult().setData(results);
}
}
... ...
... ... @@ -26,234 +26,247 @@ import com.yoho.search.service.service.IProductIndexService;
@Service
public class ProductIndexServiceImpl implements IProductIndexService, ApplicationEventPublisherAware {
private static final Logger logger = LoggerFactory.getLogger(ProductIndexServiceImpl.class);
private static final Logger logger = LoggerFactory.getLogger(ProductIndexServiceImpl.class);
@Autowired
private AggregationService aggregationService;
@Autowired
private SearchCommonService searchCommonService;
@Autowired
private AggregationService aggregationService;
@Autowired
private SearchCommonService searchCommonService;
ApplicationEventPublisher publisher;
ApplicationEventPublisher publisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
private SearchApiResult getSuccessResult(Object resultObject) {
SearchApiResult result = new SearchApiResult();
result.setCode(200);
result.setMessage("success");
result.setData(resultObject);
return result;
}
private SearchApiResult getSuccessResult(Object resultObject) {
SearchApiResult result = new SearchApiResult();
result.setCode(200);
result.setMessage("success");
result.setData(resultObject);
return result;
}
private SearchApiResult getErrorResult(String methodName, Object param, Exception e) {
logger.error("[※查询]失败:[func={}][param={}][message={}]", methodName, JsonUtil.toJson(param), e);
SearchApiResult result = new SearchApiResult();
result.setCode(500);
result.setMessage(e.getMessage());
result.setData(new JSONObject());
return result;
}
private SearchApiResult getErrorResult(String methodName, Object param, Exception e) {
logger.error("[※查询]失败:[func={}][param={}][message={}]", methodName, JsonUtil.toJson(param), e);
SearchApiResult result = new SearchApiResult();
result.setCode(500);
result.setMessage(e.getMessage());
result.setData(new JSONObject());
return result;
}
public interface Searcher {
public Object getResult() throws Exception;
}
public interface Searcher {
public Object getResult() throws Exception;
}
private SearchApiResult getSearchApiResult(String methodName, Map<String, String> paramMap, Searcher searcher) {
long begin = System.currentTimeMillis();
logger.info("[model=ProductIndexService][func={}][param={}][begin={}]", methodName, paramMap.toString(), begin);
try {
Object resultObject = searcher.getResult();
return this.getSuccessResult(resultObject);
} catch (Exception e) {
publisher.publishEvent(new SearchEvent(EventReportEnum.PRODUCTINDEXSERVICEIMPL_GETSEARCHAPIRESULT.getEventName(),
EventReportEnum.PRODUCTINDEXSERVICEIMPL_GETSEARCHAPIRESULT.getFunctionName(), EventReportEnum.PRODUCTINDEXSERVICEIMPL_GETSEARCHAPIRESULT.getMoudleName(),
"exception", IgnoreSomeException.filterSomeException(e), null));
return this.getErrorResult(methodName, paramMap, e);
} finally {
long end = System.currentTimeMillis();
logger.info("[model=ProductIndexService][func={}][param={}][end={}][cost={}ms]", methodName, paramMap.toString(), end, end - begin);
}
}
private SearchApiResult getSearchApiResult(String methodName, Map<String, String> paramMap, Searcher searcher) {
long begin = System.currentTimeMillis();
logger.info("[model=ProductIndexService][func={}][param={}][begin={}]", methodName, paramMap.toString(), begin);
try {
Object resultObject = searcher.getResult();
return this.getSuccessResult(resultObject);
} catch (Exception e) {
publisher.publishEvent(new SearchEvent(EventReportEnum.PRODUCTINDEXSERVICEIMPL_GETSEARCHAPIRESULT.getEventName(),
EventReportEnum.PRODUCTINDEXSERVICEIMPL_GETSEARCHAPIRESULT.getFunctionName(), EventReportEnum.PRODUCTINDEXSERVICEIMPL_GETSEARCHAPIRESULT.getMoudleName(),
"exception", IgnoreSomeException.filterSomeException(e), null));
return this.getErrorResult(methodName, paramMap, e);
} finally {
long end = System.currentTimeMillis();
logger.info("[model=ProductIndexService][func={}][param={}][end={}][cost={}ms]", methodName, paramMap.toString(), end, end - begin);
}
}
@Override
public SearchApiResult aggAgeLevel(Map<String, String> paramMap) {
return this.getSearchApiResult("aggAgeLevel", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getAgeLevelAggregationResult(paramMap, false);
return jsonObject.get("ageLevelAgg");
}
});
}
@Override
public SearchApiResult aggAgeLevel(Map<String, String> paramMap) {
return this.getSearchApiResult("aggAgeLevel", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getAgeLevelAggregationResult(paramMap, false);
return jsonObject.get("ageLevelAgg");
}
});
}
@Override
public SearchApiResult aggGender(Map<String, String> paramMap) {
return this.getSearchApiResult("aggGender", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getGenderNewAggregationResult(paramMap, false);
return jsonObject.get("genderAgg");
}
});
}
@Override
public SearchApiResult aggGender(Map<String, String> paramMap) {
return this.getSearchApiResult("aggGender", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getGenderNewAggregationResult(paramMap, false);
return jsonObject.get("genderAgg");
}
});
}
@Override
public SearchApiResult aggPrice(Map<String, String> paramMap) {
return this.getSearchApiResult("aggPrice", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getPriceAggregationResult(paramMap, false);
return jsonObject.get("priceAgg");
}
});
}
@Override
public SearchApiResult aggPrice(Map<String, String> paramMap) {
return this.getSearchApiResult("aggPrice", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getPriceAggregationResult(paramMap, false);
return jsonObject.get("priceAgg");
}
});
}
@Override
public SearchApiResult aggColor(Map<String, String> paramMap) {
return this.getSearchApiResult("aggColor", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getColorAggregationResult(paramMap, false);
return jsonObject.get("colorAgg");
}
});
}
@Override
public SearchApiResult aggColor(Map<String, String> paramMap) {
return this.getSearchApiResult("aggColor", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getColorAggregationResult(paramMap, false);
return jsonObject.get("colorAgg");
}
});
}
@Override
public SearchApiResult aggStyle(Map<String, String> paramMap) {
return this.getSearchApiResult("aggStyle", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getStyleAggregationResult(paramMap, false);
return jsonObject.get("styleAgg");
}
});
}
@Override
public SearchApiResult aggStyle(Map<String, String> paramMap) {
return this.getSearchApiResult("aggStyle", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getStyleAggregationResult(paramMap, false);
return jsonObject.get("styleAgg");
}
});
}
@Override
public SearchApiResult aggBrand(Map<String, String> paramMap) {
return this.getSearchApiResult("aggBrand", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getBrandAggregationResult(paramMap, false);
return jsonObject.get("brandAgg");
}
});
}
@Override
public SearchApiResult aggBrand(Map<String, String> paramMap) {
return this.getSearchApiResult("aggBrand", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getBrandAggregationResult(paramMap, false);
return jsonObject.get("brandAgg");
}
});
}
@Override
public SearchApiResult aggStandard(Map<String, String> paramMap) {
return this.getSearchApiResult("aggStandard", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getStandardAggregationResult(paramMap);
return jsonObject.get("standardAgg");
}
});
}
@Override
public SearchApiResult aggStandard(Map<String, String> paramMap) {
return this.getSearchApiResult("aggStandard", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getStandardAggregationResult(paramMap);
return jsonObject.get("standardAgg");
}
});
}
@Override
public SearchApiResult aggSize(Map<String, String> paramMap) {
return this.getSearchApiResult("aggSize", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getSizeAggregationResult(paramMap, false);
return jsonObject.get("sizeAgg");
}
});
}
@Override
public SearchApiResult aggSize(Map<String, String> paramMap) {
return this.getSearchApiResult("aggSize", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getSizeAggregationResult(paramMap, false);
return jsonObject.get("sizeAgg");
}
});
}
@Override
public SearchApiResult aggPromotion(Map<String, String> paramMap) {
return this.getSearchApiResult("aggPromotion", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getPromotionAggregationResult(paramMap, 1000);
return jsonObject.get("promotionAgg");
}
});
}
@Override
public SearchApiResult aggPromotion(Map<String, String> paramMap) {
return this.getSearchApiResult("aggPromotion", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getPromotionAggregationResult(paramMap, 1000);
return jsonObject.get("promotionAgg");
}
});
}
@Override
public SearchApiResult aggShops(Map<String, String> paramMap) {
return this.getSearchApiResult("aggShops", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getShopAggregationResult(paramMap, 100);
return jsonObject.get("shopAgg");
}
});
}
@Override
public SearchApiResult aggShops(Map<String, String> paramMap) {
return this.getSearchApiResult("aggShops", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getShopAggregationResult(paramMap, 100);
return jsonObject.get("shopAgg");
}
});
}
@Override
public SearchApiResult aggNew(Map<String, String> paramMap) {
return this.getSearchApiResult("aggNew", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getIsNewAggregationResult(paramMap, false);
Object isNewResponse = jsonObject.get("isnewAgg");
if (isNewResponse != null && ((Boolean) isNewResponse).booleanValue()) {
return "Y";
} else {
return "N";
}
}
});
}
@Override
public SearchApiResult aggLimited(Map<String, String> paramMap) {
return this.getSearchApiResult("aggLimited", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getIsLimitAggregationResult(paramMap, false);
Object islimitedAgg = jsonObject.get("islimitedAgg");
if (islimitedAgg != null && ((Boolean) islimitedAgg).booleanValue()) {
return "Y";
} else {
return "N";
}
}
});
}
@Override
public SearchApiResult aggNew(Map<String, String> paramMap) {
return this.getSearchApiResult("aggNew", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getIsNewAggregationResult(paramMap, false);
Object isNewResponse = jsonObject.get("isnewAgg");
if (isNewResponse != null && ((Boolean) isNewResponse).booleanValue()) {
return "Y";
} else {
return "N";
}
}
});
}
@Override
public SearchApiResult aggSpecialoffer(Map<String, String> paramMap) {
return this.getSearchApiResult("aggSpecialoffer", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getIsSecialofferAggregationResult(paramMap, false);
Object specialofferAgg = jsonObject.get("specialofferAgg");
if (specialofferAgg != null && ((Boolean) specialofferAgg).booleanValue()) {
return "Y";
} else {
return "N";
}
}
});
}
@Override
public SearchApiResult aggLimited(Map<String, String> paramMap) {
return this.getSearchApiResult("aggLimited", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getIsLimitAggregationResult(paramMap, false);
Object islimitedAgg = jsonObject.get("islimitedAgg");
if (islimitedAgg != null && ((Boolean) islimitedAgg).booleanValue()) {
return "Y";
} else {
return "N";
}
}
});
}
@Override
public SearchApiResult aggKeywords(Map<String, String> paramMap) {
final int randomKeywordCount = StringUtils.isBlank(paramMap.get("keyword_count")) ? 8 : Integer.parseInt(paramMap.get("keyword_count"));
return this.getSearchApiResult("aggKeywords", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getKeywordAggregationResult(paramMap, 50);
@SuppressWarnings("unchecked")
List<String> keywordList = (List<String>) jsonObject.get("keywordAgg");
return getRandomKeywords(keywordList, randomKeywordCount);
}
});
}
@Override
public SearchApiResult aggSpecialoffer(Map<String, String> paramMap) {
return this.getSearchApiResult("aggSpecialoffer", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getIsSecialofferAggregationResult(paramMap, false);
Object specialofferAgg = jsonObject.get("specialofferAgg");
if (specialofferAgg != null && ((Boolean) specialofferAgg).booleanValue()) {
return "Y";
} else {
return "N";
}
}
});
}
private List<String> getRandomKeywords(List<String> keywordList, int randomKeywordCount) {
if (keywordList == null || keywordList.size() <= randomKeywordCount) {
return keywordList;
}
return new Random().ints(0, keywordList.size()).distinct().limit(randomKeywordCount).mapToObj(index -> keywordList.get(index)).collect(Collectors.toList());
}
@Override
public SearchApiResult aggKeywords(Map<String, String> paramMap) {
final int randomKeywordCount = StringUtils.isBlank(paramMap.get("keyword_count")) ? 8 : Integer.parseInt(paramMap.get("keyword_count"));
return this.getSearchApiResult("aggKeywords", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getKeywordAggregationResult(paramMap, 50);
@SuppressWarnings("unchecked")
List<String> keywordList = (List<String>) jsonObject.get("keywordAgg");
return getRandomKeywords(keywordList, randomKeywordCount);
}
});
}
private List<String> getRandomKeywords(List<String> keywordList, int randomKeywordCount) {
if (keywordList == null || keywordList.size() <= randomKeywordCount) {
return keywordList;
}
return new Random().ints(0, keywordList.size()).distinct().limit(randomKeywordCount).mapToObj(index -> keywordList.get(index)).collect(Collectors.toList());
}
@Override
public SearchApiResult aggCustomizeTag(Map<String, String> paramMap) {
return this.getSearchApiResult("aggCustomizeTag", paramMap, new Searcher() {
@Override
public Object getResult() throws Exception {
JSONObject jsonObject = aggregationService.getCustomizeTagResult(paramMap);
return jsonObject.getJSONArray("customizeTagAgg");
}
});
}
}
... ...
... ... @@ -47,7 +47,6 @@ import com.yoho.search.service.service.ISearchRecommendService;
public class ProductListServiceImpl implements IProductListService {
private static final Logger logger = LoggerFactory.getLogger(ProductListServiceImpl.class);
private static Logger CACHE_MATCH_REQUEST = LoggerFactory.getLogger("CACHE_MATCH_REQUEST");
// 当少于20个商品时 返回智能搜索词提示
private static final int SMART_SUGGESTION_PRODUCT_LIMIT = 20;
... ...
... ... @@ -49,18 +49,25 @@
</mvc:interceptors>
<!--字符串转换器-->
<bean id="stringConverter"
class="org.springframework.http.converter.StringHttpMessageConverter">
<bean id="stringConverter" class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
<!-- json转换器 application/json -->
<bean id="jsonConverter"
class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<bean id="jsonConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
<property name="features">
<array value-type="com.alibaba.fastjson.serializer.SerializerFeature">
<value>DisableCircularReferenceDetect</value>
... ...
... ... @@ -21,8 +21,8 @@ redis.search.proxy.port =6379
redis.search.proxy.auth =
#es.cluster
search.es.cluster.name=yohosearch-dev-5.4.3
search.es.servers=192.168.102.12:9300 192.168.102.13:9300
search.es.cluster.name=yohosearch_test
search.es.servers=192.168.102.209:9300 192.168.102.216:9300
search.index.number_of_replicas=0
search.index.refresh_interval=10s
search.index.translog.flush_threshold_ops=10000
... ...
... ... @@ -148,7 +148,7 @@
</encoder>
</appender>
<!-- controller-cost appender -->
<!-- controller-performance appender -->
<appender name="CONTROLLER_PERFORMANCE_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${catalina.home}/logs/%d{yyyy-MM-dd}/controller-performance.log</fileNamePattern>
... ... @@ -163,6 +163,21 @@
</encoder>
</appender>
<!-- es-performance appender -->
<appender name="ES_PERFORMANCE_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${catalina.home}/logs/%d{yyyy-MM-dd}/es-performance.log</fileNamePattern>
<!-- 日志最大的保存天数 -->
<maxHistory>${maxHistory}</maxHistory>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>${maxFileSize}</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%-1relative - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{0} -- %msg%n</pattern>
</encoder>
</appender>
<!-- downgrade appender -->
<appender name="DOWNGRADE_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
... ... @@ -268,6 +283,12 @@
<level value="INFO"/>
<appender-ref ref="CONTROLLER_PERFORMANCE_APPENDER"/>
</logger>
<!-- ES耗时统计 -->
<logger name="ES_PERFORMANCE" additivity="false">
<level value="INFO"/>
<appender-ref ref="ES_PERFORMANCE_APPENDER"/>
</logger>
<!-- 降级日志 -->
<logger name="DOWNGRADE" additivity="false">
... ...
... ... @@ -214,7 +214,7 @@
</encoder>
</appender>
<!-- 请求超时 appender -->
<!-- controller-performance appender -->
<appender name="CONTROLLER_PERFORMANCE_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${yoho.logs.basedir}/${yoho.search.service.env.namespace}/controller-performance.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
... ... @@ -232,6 +232,24 @@
</encoder>
</appender>
<!-- es-performance appender -->
<appender name="ES_PERFORMANCE_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${yoho.logs.basedir}/${yoho.search.service.env.namespace}/es-performance.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>${yoho.logs.basedir}/${yoho.search.service.env.namespace}/archived/es-performance.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- or whenever the file size reaches 100MB -->
<maxFileSize>${yoho.logs.maxFileSize}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!-- keep 30 days' worth of history -->
<maxHistory>${yoho.logs.maxHistory}</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger:%line - %msg%n</pattern>
</encoder>
</appender>
<!-- 降级 appender -->
<appender name="DOWNGRADE_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${yoho.logs.basedir}/${yoho.search.service.env.namespace}/down-grade.log</file>
... ... @@ -346,6 +364,12 @@
<appender-ref ref="CONTROLLER_PERFORMANCE_APPENDER"/>
</logger>
<!-- ES耗时统计 -->
<logger name="ES_PERFORMANCE" additivity="false">
<level value="INFO"/>
<appender-ref ref="ES_PERFORMANCE_APPENDER"/>
</logger>
<!-- 降级日志 -->
<logger name="DOWNGRADE" additivity="false">
<level value="INFO"/>
... ...