|
|
package com.yoho.search.recall.scene.helper;
|
|
|
|
|
|
import com.alibaba.fastjson.JSON;
|
|
|
import com.yoho.search.base.utils.ISearchConstants;
|
|
|
import com.yoho.search.base.utils.ProductIndexEsField;
|
|
|
import com.yoho.search.common.cache.impls.SearchRedis;
|
|
|
import com.yoho.search.core.es.model.SearchParam;
|
|
|
import com.yoho.search.core.es.model.SearchResult;
|
|
|
import com.yoho.search.recall.scene.models.RecallReq;
|
|
|
import com.yoho.search.recall.scene.models.RecallRsp;
|
|
|
import com.yoho.search.service.base.SearchCommonService;
|
|
|
import org.apache.commons.collections.MapUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
import java.util.*;
|
|
|
|
|
|
@Component
|
|
|
public class RecallCommonService {
|
|
|
|
|
|
@Autowired
|
|
|
private SearchRedis searchRedis;
|
|
|
@Autowired
|
|
|
private SearchCommonService searchCommonService;
|
|
|
|
|
|
/**
|
|
|
* 批量召回入口
|
|
|
* @param requests
|
|
|
* @return
|
|
|
*/
|
|
|
public Map<String, RecallRsp> batchRecall(List<RecallReq> requests) {
|
|
|
//1、从缓存中获取
|
|
|
Map<String, RecallRsp> cachedResults = this.mutiGetFromCache(requests);
|
|
|
//2、过滤缓存命中的请求
|
|
|
Iterator<RecallReq> requestIterator = requests.iterator();
|
|
|
while (requestIterator.hasNext()) {
|
|
|
RecallReq request = requestIterator.next();
|
|
|
if (cachedResults.containsKey(request.toCacheKeyValue())) {
|
|
|
requestIterator.remove();
|
|
|
}
|
|
|
}
|
|
|
//3、判断是否全部命中了缓存
|
|
|
if (requests.isEmpty()) {
|
|
|
return cachedResults;
|
|
|
}
|
|
|
//4、执行查询并加入缓存
|
|
|
this.queryAndAddToCache(requests,cachedResults);
|
|
|
//5、返回结果
|
|
|
return cachedResults;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 从缓存中批量获取
|
|
|
* @param requests
|
|
|
* @return
|
|
|
*/
|
|
|
private Map<String, RecallRsp> mutiGetFromCache(List<RecallReq> requests) {
|
|
|
List<String> keys = new ArrayList<>();
|
|
|
for (RecallReq req : requests) {
|
|
|
keys.add(req.toCacheKeyValue());
|
|
|
}
|
|
|
Map<String, RecallRsp> results = new HashMap<>(requests.size());
|
|
|
List<String> cacheValues = searchRedis.searchValueOperations.multiGet(keys);
|
|
|
for (int i = 0; i < keys.size(); i++) {
|
|
|
String cacheValue = cacheValues.get(i);
|
|
|
if (cacheValue != null) {
|
|
|
results.put(keys.get(i), this.fromString(cacheValue));
|
|
|
}
|
|
|
}
|
|
|
return results;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 查询未命中缓存的请求,并加入缓存
|
|
|
* @param requests
|
|
|
* @return
|
|
|
*/
|
|
|
private void queryAndAddToCache(List<RecallReq> requests, Map<String, RecallRsp> cachedResults) {
|
|
|
//1、构造请求参数
|
|
|
List<SearchParam> searchParams = new ArrayList<>();
|
|
|
for (RecallReq request : requests) {
|
|
|
searchParams.add(request.searchParam());
|
|
|
}
|
|
|
//2、执行搜索
|
|
|
List<SearchResult> searchResults = searchCommonService.doMutiSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParams);
|
|
|
|
|
|
//3、构造结果和缓存结果
|
|
|
Map<String, String> cacheValues = new HashMap<>();
|
|
|
for (int i = 0; i < requests.size(); i++) {
|
|
|
RecallReq request = requests.get(i);
|
|
|
SearchResult searchResult = searchResults.get(i);
|
|
|
RecallRsp response = this.genRecallRspFromSearchResult(searchResult);
|
|
|
cachedResults.put(request.toCacheKeyValue(), response);
|
|
|
cacheValues.put(request.toCacheKeyValue(), this.recallRspToString(response));
|
|
|
}
|
|
|
|
|
|
//4、加入缓存
|
|
|
//TODO 设置缓存时间
|
|
|
searchRedis.searchValueOperations.multiSet(cacheValues);
|
|
|
}
|
|
|
|
|
|
private String recallRspToString(RecallRsp response) {
|
|
|
return JSON.toJSONString(response);
|
|
|
}
|
|
|
|
|
|
private RecallRsp fromString(String value) {
|
|
|
return JSON.parseObject(value, RecallRsp.class);
|
|
|
}
|
|
|
|
|
|
private RecallRsp genRecallRspFromSearchResult(SearchResult searchResult) {
|
|
|
RecallRsp response = new RecallRsp();
|
|
|
response.setTotal(searchResult.getTotal());
|
|
|
List<Map<String, Object>> results = searchResult.getResultList();
|
|
|
List<RecallRsp.RecallSkn> recallSkns = new ArrayList<>();
|
|
|
for (Map<String, Object> result : results) {
|
|
|
RecallRsp.RecallSkn recallSkn = new RecallRsp.RecallSkn();
|
|
|
recallSkn.setProductSkn(MapUtils.getInteger(result, ProductIndexEsField.productSkn, 0));
|
|
|
recallSkn.setBrandId(MapUtils.getInteger(result, ProductIndexEsField.brandId, 0));
|
|
|
recallSkn.setMiddleSortId(MapUtils.getInteger(result, ProductIndexEsField.middleSortId, 0));
|
|
|
}
|
|
|
response.setRecallSkns(recallSkns);
|
|
|
return response;
|
|
|
}
|
|
|
|
|
|
} |
...
|
...
|
|