Authored by 胡古飞

找相似功能开发

package com.yoho.search.service.restapi;
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.service.downgrade.aop.DownGradeAble;
import com.yoho.search.service.servicenew.ISearchLikeService;
import com.yoho.search.service.utils.HttpServletRequestUtils;
import com.yoho.search.service.vo.SearchApiResult;
/**
* 找相似功能
* @author hugufei
*/
@Controller
public class SearchLikeController {
@Autowired
private ISearchLikeService searchLikeService;
@DownGradeAble(key="searchLike")
@RequestMapping(method = RequestMethod.GET, value = "/searchLike")
@ResponseBody
public SearchApiResult searchLike(HttpServletRequest request){
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return searchLikeService.searchLike(paramMap);
}
}
... ...
package com.yoho.search.service.servicenew;
import java.util.Map;
import com.yoho.search.service.vo.SearchApiResult;
public interface ISearchLikeService {
/**
* 找相似功能开发
*
* @param paramMap
* @return
*/
public SearchApiResult searchLike(Map<String, String> paramMap);
}
... ...
package com.yoho.search.service.servicenew.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSONObject;
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.service.SearchCommonService;
import com.yoho.search.service.service.helper.SearchCommonHelper;
import com.yoho.search.service.service.helper.SearchServiceHelper;
import com.yoho.search.service.servicenew.ISearchLikeService;
import com.yoho.search.service.utils.SearchRequestParams;
import com.yoho.search.service.vo.SearchApiResult;
@Service
public class SearchLikeServiceImpl implements ISearchLikeService {
@Autowired
private SearchCommonHelper searchCommonHelper;
@Autowired
private SearchCommonService searchCommonService;
@Autowired
private SearchServiceHelper searchServiceHelper;
@Override
public SearchApiResult searchLike(Map<String, String> paramMap) {
// 1、获取参数
String productSkn = paramMap.get(SearchRequestParams.PARAM_SYNC_SKN);
if (StringUtils.isBlank(productSkn)) {
return new SearchApiResult().setCode(400).setMessage("请输入SKN");
}
// 2、获取当前查询的SKN的基本信息
Map<String, Object> productInfo = this.getProductSknInfo(productSkn);
if (productInfo == null) {
return new SearchApiResult().setCode(400).setMessage("SKN不存在");
}
// 3、构建找相似的参数
int pageSize = StringUtils.isBlank(paramMap.get("viewNum")) ? 10 : Integer.parseInt(paramMap.get("viewNum"));
int page = StringUtils.isBlank(paramMap.get("page")) ? 1 : Integer.parseInt(paramMap.get("page"));
if (page < 1 || pageSize < 0) {
return new SearchApiResult().setCode(400).setMessage("分页参数不合法");
}
if (pageSize > 50) {
pageSize = 100;
}
// 用来做加分
int brand_id = (int) productInfo.get("brand_id");
// 用来做过滤
int max_sort_id = (int) productInfo.get("max_sort_id");
int middle_sort_id = (int) productInfo.get("middle_sort_id");
int small_sort_id = (int) productInfo.get("small_sort_id");
String gender = (String) productInfo.get("gender");
// 用来做模糊搜索
String product_name = (String) productInfo.get("product_name");
String brand_name = (String) productInfo.get("brand_name");
SearchParam searchParam = new SearchParam();
// 2、构建多字段匹配【keyword需要有一个默认的查询字段以及权重设置,就可以拼接成一个sql】
MultiMatchQueryBuilder queryBuilder = QueryBuilders.multiMatchQuery(product_name + brand_name);
MultiMatchQueryBuilder.Type multiMatchQueryBuilderType = searchCommonHelper.getMultiMatchQueryBuilderType();
if (multiMatchQueryBuilderType != null) {
queryBuilder.type(multiMatchQueryBuilderType);
}
List<String> fields = ISearchConstants.SEARCH_DEFAULT_FIELD;
for (String field : fields) {
String[] fieldBoost = field.split("\\^");
if (fieldBoost.length == 2) {
queryBuilder.field(fieldBoost[0], Float.parseFloat(fieldBoost[1]));
} else if (fieldBoost.length == 1) {
queryBuilder.field(fieldBoost[0]);
}
}
queryBuilder.minimumShouldMatch("30%");
FunctionScoreQueryBuilder functionScoreQueryBuilder = new FunctionScoreQueryBuilder(queryBuilder);
functionScoreQueryBuilder.add(QueryBuilders.termQuery("brandId", brand_id), ScoreFunctionBuilders.weightFactorFunction(1.1f));
searchParam.setQuery(functionScoreQueryBuilder);
// 3、设置过滤条件
BoolQueryBuilder boolFilter = QueryBuilders.boolQuery();
boolFilter.must(QueryBuilders.termQuery("status", 1));
boolFilter.must(QueryBuilders.termQuery("gender", gender));
boolFilter.must(QueryBuilders.termQuery("isOutlets", 2));
boolFilter.must(QueryBuilders.termQuery("attribute", 1));
boolFilter.must(QueryBuilders.rangeQuery("storageNum").gte(1));
BoolQueryBuilder sortFilter = QueryBuilders.boolQuery();
sortFilter.should(QueryBuilders.termQuery("maxSortId", max_sort_id));
sortFilter.should(QueryBuilders.termQuery("middleSortId", middle_sort_id));
sortFilter.should(QueryBuilders.termQuery("smallSortId", small_sort_id));
boolFilter.must(sortFilter);
boolFilter.mustNot(QueryBuilders.termQuery("productSkn", productSkn));
boolFilter.mustNot(QueryBuilders.termsQuery("isSeckill", "Y"));
boolFilter.mustNot(QueryBuilders.termsQuery("isSeckill", "Y"));
searchParam.setFiter(boolFilter);
// 4、设置排序规则
List<SortBuilder> sortBuilders = new ArrayList<SortBuilder>();
sortBuilders.add(SortBuilders.fieldSort("_score").order(SortOrder.DESC));
searchParam.setSortBuilders(sortBuilders);
searchParam.setPage(page);
searchParam.setOffset((page - 1) * pageSize);
searchParam.setSize(pageSize);
// 5、执行搜索
SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParam);
SearchApiResult searchApiResult = new SearchApiResult();
JSONObject dataMap = new JSONObject();
dataMap.put("total", searchResult.getTotal());
dataMap.put("page", searchResult.getPage());
dataMap.put("page_size", searchParam.getSize());
dataMap.put("page_total", searchResult.getTotalPage());
dataMap.put("product_list", searchServiceHelper.getProductMapList(searchResult.getResultList()));
return searchApiResult.setData(dataMap);
}
private Map<String, Object> getProductSknInfo(String productSkn) {
SearchParam searchParam = new SearchParam();
searchParam.setQuery(QueryBuilders.matchAllQuery());
BoolQueryBuilder boolFilter = QueryBuilders.boolQuery();
boolFilter.must(QueryBuilders.termsQuery("productSkn", productSkn));
searchParam.setFiter(boolFilter);
searchParam.setAggregationBuilders(null);
searchParam.setPage(0);
searchParam.setOffset(0);
searchParam.setSize(1);
SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParam);
if (searchResult == null) {
return null;
}
List<Map<String, Object>> productLists = searchResult.getResultList();
if (productLists == null || productLists.isEmpty()) {
return null;
}
return searchServiceHelper.getProductMap(productLists.get(0));
}
}
... ...