Authored by hugufei

找相似代码优化【共用一份缓存即可】

... ... @@ -5,6 +5,8 @@ import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import com.yoho.search.service.scene.searchlike.BigdataSimilarSknService;
import com.yoho.search.service.scene.searchlike.SearchLikeHelper;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
... ... @@ -37,6 +39,8 @@ public class SearchLikeSecneController {
private SimilarProductService similarProductService;
@Autowired
private BigdataSimilarSknService bigdataSimilarSknService;
@Autowired
private SearchLikeHelper searchLikeHelper;
@RequestMapping(method = RequestMethod.GET, value = "/searchLike")
@ResponseBody
... ... @@ -49,14 +53,18 @@ public class SearchLikeSecneController {
@ResponseBody
public SearchApiResult searchLikeInShop(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return searchLikeInShopService.searchLikeInShop(paramMap);
int viewNum = MapUtils.getIntValue(paramMap,"viewNum",10);
SearchApiResult result = searchLikeInShopService.searchLikeInShop(paramMap);
return searchLikeHelper.buildSearchApiResultWithViewNum(result,viewNum);
}
@RequestMapping(method = RequestMethod.GET, value = "/searchLikeNotInShop")
@ResponseBody
public SearchApiResult searchLikeNotInShop(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return bigdataSimilarSknService.searchLikeSimilarSknNotInShop(paramMap);
int viewNum = MapUtils.getIntValue(paramMap,"viewNum",10);
SearchApiResult result = bigdataSimilarSknService.searchLikeSimilarSknNotInShop(paramMap);
return searchLikeHelper.buildSearchApiResultWithViewNum(result,viewNum);
}
... ...
... ... @@ -38,21 +38,22 @@ public class BigdataSimilarSknService {
/**
* 获取非重复skn
*
* @param productSknStr
* @return
*/
private List<String> getDistinctSknList(String productSknStr){
private List<String> getDistinctSknList(String productSknStr) {
List<String> results = new ArrayList<>();
String [] productSkns = productSknStr.split(",");
for (String productSkn : productSkns){
if(!results.contains(productSkn) && StringUtils.isNumeric(productSkn)){
String[] productSkns = productSknStr.split(",");
for (String productSkn : productSkns) {
if (!results.contains(productSkn) && StringUtils.isNumeric(productSkn)) {
results.add(productSkn);
}
}
return results;
}
@SearchCacheAble(cacheInMinute = 600, cacheName = "SEARCH_LIKE_NOT_IN_SHOP_SIMILAR", includeParams = { "product_skn", "viewNum" })
@SearchCacheAble(cacheInMinute = 600, cacheName = "SEARCH_LIKE_NOT_IN_SHOP_SIMILAR", includeParams = {"product_skn"})
public SearchApiResult searchLikeSimilarSknNotInShop(Map<String, String> paramMap) {
try {
// 1、获取参数
... ... @@ -61,7 +62,7 @@ public class BigdataSimilarSknService {
return new SearchApiResult().setCode(400).setMessage("请输入SKN");
}
// 2、检测分页参数【默认30条,最多60条】
int pageSize = searchLikeHelper.getPageSize(paramMap);
int pageSize = 30;
// 3、获取当前查询的SKN的基本信息
JSONObject productInfoInEs = searchLikeHelper.getProductInfoInEs(productSkn);
if (productInfoInEs == null) {
... ... @@ -87,14 +88,14 @@ public class BigdataSimilarSknService {
searchParams.add(this.builderSimilarSknSearchParam(productInfoInEs, diffShopActionSimilarSkns, true));
//5.3)文字兜底[性别+不同店铺+文字相似性]
searchParams.add( searchLikeHelper.builderSearchLikeNotInShopCharactersSearchParam(productInfoInEs, Arrays.asList(productSkn), pageSize,true));
searchParams.add(searchLikeHelper.builderSearchLikeNotInShopCharactersSearchParam(productInfoInEs, Arrays.asList(productSkn), pageSize, true));
// 6、获取搜索结果
List<List<Map<String, Object>>> queryResults = searchLikeHelper.queryProductLists(searchParams);
// 7、处理图片和行为的顺序
List<Map<String, Object>> diffShopImgSimilarProducts = this.sortProductList(queryResults.get(0),diffShopImgSimilarSkns,pageSize/3);
List<Map<String, Object>> diffShopActionSimilarProducts = this.sortProductList(queryResults.get(1),diffShopActionSimilarSkns,pageSize/3);
List<Map<String, Object>> diffShopImgSimilarProducts = this.sortProductList(queryResults.get(0), diffShopImgSimilarSkns, pageSize / 3);
List<Map<String, Object>> diffShopActionSimilarProducts = this.sortProductList(queryResults.get(1), diffShopActionSimilarSkns, pageSize / 3);
// 8、获取临时结果
List<Map<String, Object>> tempProductList = new ArrayList<>();
... ... @@ -102,11 +103,11 @@ public class BigdataSimilarSknService {
tempProductList.addAll(diffShopActionSimilarProducts);
tempProductList.addAll(queryResults.get(2));
if (tempProductList.size() > pageSize) {
tempProductList = CollectionUtils.safeSubList(tempProductList,0, pageSize);
tempProductList = CollectionUtils.safeSubList(tempProductList, 0, pageSize);
}
// 8.1 保留偶数
if(tempProductList.size()%2>0){
tempProductList = CollectionUtils.safeSubList(tempProductList,0, tempProductList.size()-1);
if (tempProductList.size() % 2 > 0) {
tempProductList = CollectionUtils.safeSubList(tempProductList, 0, tempProductList.size() - 1);
}
// 9、构造真实返回结果
List<Map<String, Object>> productListResults = new ArrayList<>();
... ... @@ -114,10 +115,6 @@ public class BigdataSimilarSknService {
productListResults = productListHelper.buildReturnInfoByEsSourceList(tempProductList);
}
JSONObject result = new JSONObject();
result.put("page", 1);
result.put("page_total", 1);
result.put("page_size", pageSize);
result.put("total", productListResults.size());
result.put("product_info", searchLikeHelper.genProductInfoResult(productInfoInEs));
result.put("product_list", productListResults);
return new SearchApiResult().setData(result);
... ... @@ -129,25 +126,26 @@ public class BigdataSimilarSknService {
/**
* 按productSkn顺序截取商品条数-注意循环引用的问题
*
* @param esProductList
* @param sortedProductSkns
* @param size
* @return
*/
private List<Map<String, Object>> sortProductList(List<Map<String, Object>> esProductList,List<String> sortedProductSkns,int size){
private List<Map<String, Object>> sortProductList(List<Map<String, Object>> esProductList, List<String> sortedProductSkns, int size) {
List<Map<String, Object>> results = new ArrayList<>();
if(esProductList==null || esProductList.isEmpty()){
if (esProductList == null || esProductList.isEmpty()) {
return results;
}
if(sortedProductSkns==null || sortedProductSkns.isEmpty() || size<=0){
if (sortedProductSkns == null || sortedProductSkns.isEmpty() || size <= 0) {
return results;
}
Map<String, Map<String, Object>> productMap = CollectionUtils.toMap(esProductList,(product)->MapUtils.getString(product,ProductIndexEsField.productSkn,""));
for (String productSkn : sortedProductSkns){
if(productMap.containsKey(productSkn)){
Map<String, Map<String, Object>> productMap = CollectionUtils.toMap(esProductList, (product) -> MapUtils.getString(product, ProductIndexEsField.productSkn, ""));
for (String productSkn : sortedProductSkns) {
if (productMap.containsKey(productSkn)) {
results.add(new HashMap<>(productMap.get(productSkn)));//注意循环引用
}
if(results.size()>=size){
if (results.size() >= size) {
break;
}
}
... ... @@ -157,16 +155,17 @@ public class BigdataSimilarSknService {
/**
* 构建SimilarSknSearchParam[考虑productSkns为空的情况]
*
* @param productInfoInEs
* @param productSkns
* @param filterSameSort
* @return
*/
private SearchParam builderSimilarSknSearchParam(JSONObject productInfoInEs, List<String> productSkns,boolean filterSameSort) {
private SearchParam builderSimilarSknSearchParam(JSONObject productInfoInEs, List<String> productSkns, boolean filterSameSort) {
// 1、设置SearchParam
SearchParam searchParam = new SearchParam();
// 2)设置query和filter
searchParam.setFiter(this.builderSimilarSknFilter(productInfoInEs, productSkns,filterSameSort));
searchParam.setFiter(this.builderSimilarSknFilter(productInfoInEs, productSkns, filterSameSort));
// 3、设置分页参数
searchParam.setOffset(0);
searchParam.setSize(productSkns.size());
... ... @@ -176,7 +175,7 @@ public class BigdataSimilarSknService {
return searchParam;
}
private QueryBuilder builderSimilarSknFilter(JSONObject productInfoInEs, List<String> inProductSkns,boolean filterSameSort) {
private QueryBuilder builderSimilarSknFilter(JSONObject productInfoInEs, List<String> inProductSkns, boolean filterSameSort) {
String isGlobalInEs = productInfoInEs.getString(ProductIndexEsField.isGlobal);
boolean isGlobal = "Y".equalsIgnoreCase(isGlobalInEs);
BoolQueryBuilder boolFilter = searchLikeHelper.genDefaultSearchLikeFilter(null, isGlobal);
... ...
package com.yoho.search.service.scene.searchlike;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.base.utils.CollectionUtils;
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.SearchApiResult;
import com.yoho.search.models.SearchFieldBoost;
import com.yoho.search.service.base.SearchCommonService;
import com.yoho.search.service.base.index.ProductIndexBaseService;
... ... @@ -21,7 +24,6 @@ import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.PostConstruct;
import java.util.*;
... ... @@ -91,6 +93,49 @@ public class SearchLikeHelper {
}
/**
* 根据缓存结果,截取viewNum
* @param searchApiResult
* @param viewNum
* @return
*/
public SearchApiResult buildSearchApiResultWithViewNum(SearchApiResult searchApiResult,int viewNum) {
//1、结果判断
if(searchApiResult.getData()==null || searchApiResult.getCode()!=200){
return searchApiResult;
}
//2、参数判断
JSONObject data = (JSONObject)searchApiResult.getData();
JSONArray productListJSONArray = data.getJSONArray("product_list");
if(productListJSONArray==null || productListJSONArray.isEmpty()){
data.put("page", 1);
data.put("page_size", viewNum);
data.put("total", 0);
data.put("page_total", 0);
data.put("product_list", new ArrayList<>());
return searchApiResult;
}
//3、截取productList
List<JSONObject> productList = new ArrayList<>();
for (int i =0;i<productListJSONArray.size();i++){
if(productList.size()>=viewNum){
break;
}
productList.add(productListJSONArray.getJSONObject(i));
}
//4、保留偶数
if (productList.size() % 2 > 0) {
productList = CollectionUtils.safeSubList(productList, 0, productList.size() - 1);
}
//5、构造返回结果
data.put("page", 1);
data.put("page_size", viewNum);
data.put("total", productList.size());
data.put("page_total", 1);
data.put("product_list", productList);
return searchApiResult;
}
/**
* 获取SKN在ES中的原生信息
*
* @param productSkn
... ...
... ... @@ -50,7 +50,7 @@ public class SearchLikeInShopService {
* @param paramMap
* @return
*/
@SearchCacheAble(cacheInMinute = 600, cacheName = "SEARCH_LIKE_IN_SHOP", includeParams = { "product_skn", "viewNum" })
@SearchCacheAble(cacheInMinute = 600, cacheName = "SEARCH_LIKE_IN_SHOP", includeParams = { "product_skn"})
public SearchApiResult searchLikeInShop(Map<String, String> paramMap) {
try {
// 1、获取参数
... ... @@ -58,8 +58,8 @@ public class SearchLikeInShopService {
if (StringUtils.isBlank(productSkn)) {
return new SearchApiResult().setCode(400).setMessage("请输入SKN");
}
// 2、检测分页参数【默认30条,最多60条】
int pageSize = searchLikeHelper.getPageSize(paramMap);
// 2、检测分页参数【默认30条】
int viewNum = 30;
// 3、获取当前查询的SKN的基本信息
JSONObject productInfoInEs = searchLikeHelper.getProductInfoInEs(productSkn);
... ... @@ -69,12 +69,12 @@ public class SearchLikeInShopService {
// 4、设置SearchParams
List<SearchParam> searchParams = new ArrayList<SearchParam>();
searchParams.add(this.builderSearchParam(productInfoInEs, Arrays.asList(productSkn), pageSize));
searchParams.add(this.builderSearchParam(productInfoInEs, Arrays.asList(productSkn), viewNum));
// 5、获取搜索结果[截取条数]
List<Map<String, Object>> tempProductList = searchLikeHelper.queryProductList(searchParams);
if (tempProductList.size() > pageSize) {
tempProductList = CollectionUtils.safeSubList(tempProductList,0, pageSize);
if (tempProductList.size() > viewNum) {
tempProductList = CollectionUtils.safeSubList(tempProductList,0, viewNum);
}
// 6、构造真实返回结果
... ... @@ -83,10 +83,6 @@ public class SearchLikeInShopService {
productListResults = productListHelper.buildReturnInfoByEsSourceList(tempProductList);
}
JSONObject result = new JSONObject();
result.put("page", 1);
result.put("page_total", 1);
result.put("page_size", pageSize);
result.put("total", productListResults.size());
result.put("product_info", searchLikeHelper.genProductInfoResult(productInfoInEs));
result.put("product_list", productListResults);
return new SearchApiResult().setData(result);
... ...