|
@@ -0,0 +1,102 @@
|
|
|
+package com.tzld.piaoquan.recommend.server.service.recall.strategy;
|
|
|
+
|
|
|
+import com.tzld.piaoquan.recommend.server.model.Video;
|
|
|
+import com.tzld.piaoquan.recommend.server.service.filter.FilterParam;
|
|
|
+import com.tzld.piaoquan.recommend.server.service.filter.FilterResult;
|
|
|
+import com.tzld.piaoquan.recommend.server.service.filter.FilterService;
|
|
|
+import com.tzld.piaoquan.recommend.server.service.recall.FilterParamFactory;
|
|
|
+import com.tzld.piaoquan.recommend.server.service.recall.RecallParam;
|
|
|
+import com.tzld.piaoquan.recommend.server.service.recall.RecallStrategy;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.collections4.CollectionUtils;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.apache.commons.lang3.tuple.MutablePair;
|
|
|
+import org.apache.commons.lang3.tuple.Pair;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Qualifier;
|
|
|
+import org.springframework.data.redis.core.RedisTemplate;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+@Component
|
|
|
+@Slf4j
|
|
|
+public class PrioriProvinceRovnRecallStrategy implements RecallStrategy {
|
|
|
+ private final String CLASS_NAME = this.getClass().getSimpleName();
|
|
|
+ @Autowired
|
|
|
+ private FilterService filterService;
|
|
|
+ @Autowired
|
|
|
+ @Qualifier("redisTemplate")
|
|
|
+ public RedisTemplate<String, String> redisTemplate;
|
|
|
+
|
|
|
+ public static final String PUSH_FROM = "priori_province_rovn";
|
|
|
+ public static final String redisKeyPrefix = "priori_province_rovn_recall";
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String pushFrom() {
|
|
|
+ return PUSH_FROM;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<Video> recall(RecallParam param) {
|
|
|
+ List<Video> videosResult = new ArrayList<>();
|
|
|
+ try {
|
|
|
+ String province = param.getProvince().replaceAll("省$", "");
|
|
|
+ String redisKey = String.format("%s:%s", redisKeyPrefix, province);
|
|
|
+ String redisValue = redisTemplate.opsForValue().get(redisKey);
|
|
|
+ if (null == redisValue || redisValue.isEmpty()) {
|
|
|
+ return videosResult;
|
|
|
+ }
|
|
|
+ Pair<List<Long>, Map<Long, Double>> pair = parsePair(redisValue, param.getVideoId(), 50);
|
|
|
+ fillVideoResult(param, pair, videosResult);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("recall is wrong in {}, error={}", CLASS_NAME, e);
|
|
|
+ }
|
|
|
+ return videosResult;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Pair<List<Long>, Map<Long, Double>> parsePair(String data, long headVid, int size) {
|
|
|
+ List<Long> idsList = new ArrayList<>();
|
|
|
+ Map<Long, Double> scoresMap = new HashMap<>();
|
|
|
+ if (!StringUtils.isBlank(data)) {
|
|
|
+ String[] cells = data.split("\t");
|
|
|
+ if (2 == cells.length) {
|
|
|
+ List<Long> ids = Arrays.stream(cells[0].split(",")).map(Long::valueOf).collect(Collectors.toList());
|
|
|
+ List<Double> scores = Arrays.stream(cells[1].split(",")).map(Double::valueOf).collect(Collectors.toList());
|
|
|
+ if (!ids.isEmpty() && ids.size() == scores.size()) {
|
|
|
+ int minSize = Math.min(size, ids.size());
|
|
|
+ for (int i = 0; i < minSize; ++i) {
|
|
|
+ long id = ids.get(i);
|
|
|
+ double score = scores.get(i);
|
|
|
+ if (headVid != id && !scoresMap.containsKey(id)) {
|
|
|
+ idsList.add(id);
|
|
|
+ scoresMap.put(id, score);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return new MutablePair<>(idsList, scoresMap);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void fillVideoResult(RecallParam param, Pair<List<Long>, Map<Long, Double>> pair, List<Video> videosResult) {
|
|
|
+ if (null != pair) {
|
|
|
+ List<Long> ids = pair.getLeft();
|
|
|
+ Map<Long, Double> scoresMap = pair.getRight();
|
|
|
+ if (null != ids && null != scoresMap && !ids.isEmpty()) {
|
|
|
+ FilterParam filterParam = FilterParamFactory.create(param, ids);
|
|
|
+ FilterResult filterResult = filterService.filter(filterParam);
|
|
|
+ if (null != filterResult && CollectionUtils.isNotEmpty(filterResult.getVideoIds())) {
|
|
|
+ filterResult.getVideoIds().forEach(vid -> {
|
|
|
+ Video video = new Video();
|
|
|
+ video.setVideoId(vid);
|
|
|
+ video.setRovScore(scoresMap.getOrDefault(vid, 0D));
|
|
|
+ video.setPushFrom(pushFrom());
|
|
|
+ videosResult.add(video);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|