Explorar o código

feat:低VOV视频过滤策略迭代

zhaohaipeng hai 6 meses
pai
achega
61917ea2e1

+ 65 - 8
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/filter/strategy/VovLowerStrategy.java

@@ -3,6 +3,9 @@ package com.tzld.piaoquan.recommend.server.service.filter.strategy;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.TypeReference;
 import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
 import com.tzld.piaoquan.recommend.server.service.filter.FilterParam;
 import com.tzld.piaoquan.recommend.server.service.filter.FilterStrategy;
 import lombok.extern.slf4j.Slf4j;
@@ -12,11 +15,15 @@ import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import javax.annotation.Nonnull;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 @Slf4j
@@ -32,17 +39,65 @@ public class VovLowerStrategy implements FilterStrategy {
 
     private static final String KEY_FORMAT = "redis:vid_vov_daily4filter:%d";
 
+    private static final String LOWER_VOV_VID_KEY_FORMAT = "redis:lower_vov_vid:%s";
+    private static final DateTimeFormatter YYYY_MM_DD = DateTimeFormatter.ofPattern("yyyyMMdd");
+
+    /**
+     * 低VOV视频ID集合缓存, 五分钟有效期
+     */
+    private final LoadingCache<String, Set<Long>> lowerVovVidCache = CacheBuilder.newBuilder()
+            .expireAfterWrite(5, TimeUnit.MINUTES)
+            .build(new CacheLoader<String, Set<Long>>() {
+                @Override
+                public Set<Long> load(@Nonnull String key) {
+                    Set<String> members = redisTemplate.opsForSet().members(key);
+                    if (CollectionUtils.isEmpty(members)) {
+                        return Collections.emptySet();
+                    }
+                    return members.stream()
+                            .map(Long::parseLong)
+                            .collect(Collectors.toSet());
+                }
+            });
+
     @Override
     public List<Long> filter(FilterParam param) {
 
-        List<Long> result = new ArrayList<>();
-
         List<Long> videoIds = param.getVideoIds();
         if (CollectionUtils.isEmpty(videoIds)) {
             log.info("VOV过滤 -- videoIds为空,跳过");
-            return result;
+            return new ArrayList<>();
+        }
+
+        List<Long> result = new ArrayList<>(videoIds.size());
+        List<Long> removeIds = new ArrayList<>();
+
+        String dt = LocalDate.now().format(YYYY_MM_DD);
+        String redisKey = String.format(LOWER_VOV_VID_KEY_FORMAT, dt);
+        try {
+            Set<Long> lowerVovVidSet = lowerVovVidCache.get(redisKey);
+
+            for (Long videoId : videoIds) {
+                if (lowerVovVidSet.contains(videoId)) {
+                    removeIds.add(videoId);
+                } else {
+                    result.add(videoId);
+                }
+            }
+
+        } catch (Exception e) {
+            log.error("VOV过滤V2 -- 从缓存中获取低VOV视频ID集合异常: ", e);
         }
 
+        log.info("VOV过滤V2 -- 本次召回的ID列表为: {}, 被过滤掉的ID列表为: {}, 剩下的ID列表为: {}", videoIds, removeIds, result);
+
+        return result;
+    }
+
+    public List<Long> filterV1(List<Long> videoIds) {
+
+        List<Long> result = new ArrayList<>(videoIds.size());
+
         List<String> redisKeys = videoIds.stream()
                 .map(r -> String.format(KEY_FORMAT, r))
                 .collect(Collectors.toList());
@@ -65,12 +120,11 @@ public class VovLowerStrategy implements FilterStrategy {
             result.add(videoId);
         }
 
-        log.info("VOV -- 本次召回的ID列表为: {}, 被过滤掉的ID列表为: {}, 剩下的ID列表为: {}", videoIds, removeIds, result);
+        log.info("VOV过滤V1 -- 本次召回的ID列表为: {}, 被过滤掉的ID列表为: {}, 剩下的ID列表为: {}", videoIds, removeIds, result);
 
         return result;
     }
 
-
     private boolean isShouldFilter(String vovInfo) {
         try {
 
@@ -135,4 +189,7 @@ public class VovLowerStrategy implements FilterStrategy {
 
     }
 
+    @Scheduled(cron = "0 0/5 * * * ? ")
+    public void cronSync() {
+    }
 }