浏览代码

homepage recommend

丁云鹏 1 年之前
父节点
当前提交
eb4afcb0fc
共有 30 个文件被更改,包括 450 次插入469 次删除
  1. 1 1
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/recommend/Recommend.java
  2. 30 102
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/recommend/Video.java
  3. 2 8
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/recommend/VideoOrBuilder.java
  4. 0 18
      recommend-server-client/src/main/proto/com/tzld/piaoquan/recommend/server/hello.proto
  5. 7 7
      recommend-server-client/src/main/proto/com/tzld/piaoquan/recommend/server/recommend.proto
  6. 0 26
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/MidService.java
  7. 85 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/PreViewedService.java
  8. 8 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/RecommendConstants.java
  9. 100 23
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/RecommendService.java
  10. 101 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/ViewedService.java
  11. 6 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/filter/FilterParam.java
  12. 4 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/filter/FilterResult.java
  13. 44 4
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/filter/FilterService.java
  14. 14 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/filter/FlowPoolFilterService.java
  15. 0 70
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/filter/FlowPoolWithLevelFilterService.java
  16. 0 80
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/filter/FlowPoolWithLevelScoreFilterService.java
  17. 0 80
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/filter/FlowPoolWithScoreFilterService.java
  18. 14 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/filter/RegionFilterService.java
  19. 1 20
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/filter/VideoFilterService.java
  20. 0 4
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/RankService.java
  21. 1 1
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/RecallParam.java
  22. 1 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/SpecialRegionRecallStrategy.java
  23. 3 3
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractFlowPoolWithLevelRecallStrategy.java
  24. 13 14
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractFlowPoolWithLevelScoreRecallStrategy.java
  25. 3 3
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractFlowPoolWithScoreRecallStrategy.java
  26. 4 2
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractRegionRecallStrategy.java
  27. 1 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/Region24HRecallStrategy.java
  28. 2 1
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/RegionHRecallStrategy.java
  29. 3 1
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/RegionRelative24HDupRecallStrategy.java
  30. 2 1
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/RegionRelative24HRecallStrategy.java

+ 1 - 1
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/recommend/Recommend.java

@@ -56,7 +56,7 @@ public final class Recommend {
       "se\022\027\n\006result\030\001 \001(\0132\007.Result\022\025\n\005video\030\002 \003" +
       "(\0132\006.Video\"v\n\005Video\022\020\n\010video_id\030\001 \001(\003\022\021\n" +
       "\trov_score\030\002 \001(\001\022\021\n\tpush_from\030\003 \001(\t\022\017\n\007a" +
-      "b_code\030\004 \001(\t\022\022\n\nsort_score\030\005 \001(\t\022\020\n\010posi" +
+      "b_code\030\004 \001(\t\022\022\n\nsort_score\030\005 \001(\001\022\020\n\010posi" +
       "tion\030\006 \001(\0052^\n\020RecommendService\022J\n\021Homepa" +
       "geRecommend\022\031.HomepageRecommendRequest\032\032" +
       ".HomepageRecommendResponseB7\n0com.tzld.p" +

+ 30 - 102
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/recommend/Video.java

@@ -17,8 +17,7 @@ private static final long serialVersionUID = 0L;
   }
   private Video() {
     pushFrom_ = "";
-    abCode_ = "";toBuilder
-    sortScore_ = "";
+    abCode_ = "";
   }
 
   @java.lang.Override
@@ -73,10 +72,9 @@ private static final long serialVersionUID = 0L;
             abCode_ = s;
             break;
           }
-          case 42: {
-            java.lang.String s = input.readStringRequireUtf8();
+          case 41: {
 
-            sortScore_ = s;
+            sortScore_ = input.readDouble();
             break;
           }
           case 48: {
@@ -215,41 +213,14 @@ private static final long serialVersionUID = 0L;
   }
 
   public static final int SORT_SCORE_FIELD_NUMBER = 5;
-  private volatile java.lang.Object sortScore_;
+  private double sortScore_;
   /**
-   * <code>string sort_score = 5;</code>
+   * <code>double sort_score = 5;</code>
    * @return The sortScore.
    */
   @java.lang.Override
-  public java.lang.String getSortScore() {
-    java.lang.Object ref = sortScore_;
-    if (ref instanceof java.lang.String) {
-      return (java.lang.String) ref;
-    } else {
-      com.google.protobuf.ByteString bs = 
-          (com.google.protobuf.ByteString) ref;
-      java.lang.String s = bs.toStringUtf8();
-      sortScore_ = s;
-      return s;
-    }
-  }
-  /**
-   * <code>string sort_score = 5;</code>
-   * @return The bytes for sortScore.
-   */
-  @java.lang.Override
-  public com.google.protobuf.ByteString
-      getSortScoreBytes() {
-    java.lang.Object ref = sortScore_;
-    if (ref instanceof java.lang.String) {
-      com.google.protobuf.ByteString b = 
-          com.google.protobuf.ByteString.copyFromUtf8(
-              (java.lang.String) ref);
-      sortScore_ = b;
-      return b;
-    } else {
-      return (com.google.protobuf.ByteString) ref;
-    }
+  public double getSortScore() {
+    return sortScore_;
   }
 
   public static final int POSITION_FIELD_NUMBER = 6;
@@ -289,8 +260,8 @@ private static final long serialVersionUID = 0L;
     if (!getAbCodeBytes().isEmpty()) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 4, abCode_);
     }
-    if (!getSortScoreBytes().isEmpty()) {
-      com.google.protobuf.GeneratedMessageV3.writeString(output, 5, sortScore_);
+    if (sortScore_ != 0D) {
+      output.writeDouble(5, sortScore_);
     }
     if (position_ != 0) {
       output.writeInt32(6, position_);
@@ -318,8 +289,9 @@ private static final long serialVersionUID = 0L;
     if (!getAbCodeBytes().isEmpty()) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, abCode_);
     }
-    if (!getSortScoreBytes().isEmpty()) {
-      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, sortScore_);
+    if (sortScore_ != 0D) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeDoubleSize(5, sortScore_);
     }
     if (position_ != 0) {
       size += com.google.protobuf.CodedOutputStream
@@ -349,8 +321,9 @@ private static final long serialVersionUID = 0L;
         .equals(other.getPushFrom())) return false;
     if (!getAbCode()
         .equals(other.getAbCode())) return false;
-    if (!getSortScore()
-        .equals(other.getSortScore())) return false;
+    if (java.lang.Double.doubleToLongBits(getSortScore())
+        != java.lang.Double.doubleToLongBits(
+            other.getSortScore())) return false;
     if (getPosition()
         != other.getPosition()) return false;
     if (!unknownFields.equals(other.unknownFields)) return false;
@@ -375,7 +348,8 @@ private static final long serialVersionUID = 0L;
     hash = (37 * hash) + AB_CODE_FIELD_NUMBER;
     hash = (53 * hash) + getAbCode().hashCode();
     hash = (37 * hash) + SORT_SCORE_FIELD_NUMBER;
-    hash = (53 * hash) + getSortScore().hashCode();
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        java.lang.Double.doubleToLongBits(getSortScore()));
     hash = (37 * hash) + POSITION_FIELD_NUMBER;
     hash = (53 * hash) + getPosition();
     hash = (29 * hash) + unknownFields.hashCode();
@@ -519,7 +493,7 @@ private static final long serialVersionUID = 0L;
 
       abCode_ = "";
 
-      sortScore_ = "";
+      sortScore_ = 0D;
 
       position_ = 0;
 
@@ -617,9 +591,8 @@ private static final long serialVersionUID = 0L;
         abCode_ = other.abCode_;
         onChanged();
       }
-      if (!other.getSortScore().isEmpty()) {
-        sortScore_ = other.sortScore_;
-        onChanged();
+      if (other.getSortScore() != 0D) {
+        setSortScore(other.getSortScore());
       }
       if (other.getPosition() != 0) {
         setPosition(other.getPosition());
@@ -867,78 +840,33 @@ private static final long serialVersionUID = 0L;
       return this;
     }
 
-    private java.lang.Object sortScore_ = "";
+    private double sortScore_ ;
     /**
-     * <code>string sort_score = 5;</code>
+     * <code>double sort_score = 5;</code>
      * @return The sortScore.
      */
-    public java.lang.String getSortScore() {
-      java.lang.Object ref = sortScore_;
-      if (!(ref instanceof java.lang.String)) {
-        com.google.protobuf.ByteString bs =
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        sortScore_ = s;
-        return s;
-      } else {
-        return (java.lang.String) ref;
-      }
-    }
-    /**
-     * <code>string sort_score = 5;</code>
-     * @return The bytes for sortScore.
-     */
-    public com.google.protobuf.ByteString
-        getSortScoreBytes() {
-      java.lang.Object ref = sortScore_;
-      if (ref instanceof String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        sortScore_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
+    @java.lang.Override
+    public double getSortScore() {
+      return sortScore_;
     }
     /**
-     * <code>string sort_score = 5;</code>
+     * <code>double sort_score = 5;</code>
      * @param value The sortScore to set.
      * @return This builder for chaining.
      */
-    public Builder setSortScore(
-        java.lang.String value) {
-      if (value == null) {
-    throw new NullPointerException();
-  }
-  
+    public Builder setSortScore(double value) {
+      
       sortScore_ = value;
       onChanged();
       return this;
     }
     /**
-     * <code>string sort_score = 5;</code>
+     * <code>double sort_score = 5;</code>
      * @return This builder for chaining.
      */
     public Builder clearSortScore() {
       
-      sortScore_ = getDefaultInstance().getSortScore();
-      onChanged();
-      return this;
-    }
-    /**
-     * <code>string sort_score = 5;</code>
-     * @param value The bytes for sortScore to set.
-     * @return This builder for chaining.
-     */
-    public Builder setSortScoreBytes(
-        com.google.protobuf.ByteString value) {
-      if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-      
-      sortScore_ = value;
+      sortScore_ = 0D;
       onChanged();
       return this;
     }

+ 2 - 8
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/recommend/VideoOrBuilder.java

@@ -44,16 +44,10 @@ public interface VideoOrBuilder extends
       getAbCodeBytes();
 
   /**
-   * <code>string sort_score = 5;</code>
+   * <code>double sort_score = 5;</code>
    * @return The sortScore.
    */
-  java.lang.String getSortScore();
-  /**
-   * <code>string sort_score = 5;</code>
-   * @return The bytes for sortScore.
-   */
-  com.google.protobuf.ByteString
-      getSortScoreBytes();
+  double getSortScore();
 
   /**
    * <code>int32 position = 6;</code>

+ 0 - 18
recommend-server-client/src/main/proto/com/tzld/piaoquan/recommend/server/hello.proto

@@ -1,18 +0,0 @@
-syntax = "proto3";
-
-option java_multiple_files = true;
-option java_package = "com.tzld.piaoquan.recommend.server.gen.demo";
-option java_generic_services = true;
-
-service HelloService {
-  rpc SayHello (HelloRequest) returns (HelloResponse);
-}
-
-message HelloRequest {
-  string greeting = 1;
-}
-
-message HelloResponse {
-  string reply = 1;
-}
-

+ 7 - 7
recommend-server-client/src/main/proto/com/tzld/piaoquan/recommend/server/recommend.proto

@@ -14,7 +14,7 @@ message HomepageRecommendRequest {
   string uid = 3;
   string category_id = 4;
   int32 size = 5; // default 4
-  string app_type = 6; // default 4
+  int32 app_type = 6; // default 4
   string algo_type = 7;
   string client_info = 8;
   string ab_exp_info = 9;
@@ -37,12 +37,12 @@ message HomepageRecommendResponse {
 }
 
 message Video{
-    int64 video_id = 1;
-    double rov_score = 2;
-    string push_from = 3;
-    string ab_code = 4;
-    string sort_score = 5;
-    int32 position = 6;
+  int64 video_id = 1;
+  double rov_score = 2;
+  string push_from = 3;
+  string ab_code = 4;
+  double sort_score = 5;
+  int32 position = 6;
 }
 
 service RecommendService {

+ 0 - 26
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/MidService.java

@@ -1,26 +0,0 @@
-package com.tzld.piaoquan.recommend.server.service;
-
-import org.springframework.stereotype.Service;
-
-import java.util.Collections;
-import java.util.Set;
-
-/**
- * @author dyp
- */
-@Service
-public class MidService {
-    public Set<String> getSpecialMids() {
-        // TODO
-        //def get_special_mid_list():
-        //    redis_helper = RedisHelper()
-        //    special_mid_list = redis_helper.get_data_from_set(key_name=config_.KEY_NAME_SPECIAL_MID)
-        //    if special_mid_list:
-        //        return special_mid_list
-        //    else:
-        //        return []
-        //     KEY_NAME_SPECIAL_MID = 'special:mid'
-
-        return Collections.emptySet();
-    }
-}

+ 85 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/PreViewedService.java

@@ -0,0 +1,85 @@
+package com.tzld.piaoquan.recommend.server.service;
+
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.Cursor;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ScanOptions;
+import org.springframework.stereotype.Service;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author dyp
+ */
+@Service
+@Slf4j
+public class PreViewedService {
+    @Autowired
+    private RedisTemplate<String, Long> redisTemplate;
+
+    public static final String KEY_PRE_VIEWED_FORMAT = "previewed:videos:%s:%s";
+
+    private LoadingCache<String, Set<Long>> preViewedCache = CacheBuilder.newBuilder()
+            .maximumSize(100000) // TODO 评估容量
+            .refreshAfterWrite(10, TimeUnit.SECONDS)
+            .expireAfterWrite(10, TimeUnit.SECONDS)
+            .expireAfterAccess(10, TimeUnit.SECONDS)
+            .build(new CacheLoader<String, Set<Long>>() {
+                @Override
+                public Set<Long> load(String key) throws Exception {
+                    Set<Long> result = new HashSet<>();
+                    Cursor<Long> cursor = redisTemplate.opsForSet().scan(key, ScanOptions.NONE);
+                    try {
+                        while (cursor != null && cursor.hasNext()) {
+                            Long videoId = cursor.next();
+                            result.add(videoId);
+                        }
+                    } catch (Exception e) {
+                        log.error("sScan", e);
+                    } finally {
+                        try {
+                            if (!cursor.isClosed()) {
+                                cursor.close();
+                            }
+                        } catch (IOException e) {
+                            log.error("sScan", e);
+                        }
+                    }
+                    return result;
+                }
+            });
+
+    public void updateCache(int appType, String mid, Long[] videoIds) {
+        if (StringUtils.isBlank(mid)
+                || videoIds == null
+                || videoIds.length == 0) {
+            return;
+        }
+        String key = String.format(KEY_PRE_VIEWED_FORMAT, appType, mid);
+        redisTemplate.opsForSet().add(key, videoIds);
+        redisTemplate.expire(key, 30, TimeUnit.MINUTES);
+    }
+
+    public Set<Long> getVideoIds(int appType, String mid) {
+        if (StringUtils.isBlank(mid)) {
+            return Collections.emptySet();
+        }
+        String key = String.format(KEY_PRE_VIEWED_FORMAT, appType, mid);
+        try {
+            return preViewedCache.get(key);
+        } catch (Exception e) {
+            log.error("get pre viewed cache error! key={}", key, e);
+        }
+        return Collections.emptySet();
+    }
+
+}

+ 8 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/RecommendConstants.java

@@ -0,0 +1,8 @@
+package com.tzld.piaoquan.recommend.server.service;
+
+/**
+ * @author dyp
+ */
+public class RecommendConstants {
+    public static final String KEY_PRE_VIEWED_FORMAT = "previewed:videos:%s:%s";
+}

+ 100 - 23
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/RecommendService.java

@@ -13,6 +13,10 @@ import com.tzld.piaoquan.recommend.server.service.rank.RankService;
 import com.tzld.piaoquan.recommend.server.service.recall.RecallParam;
 import com.tzld.piaoquan.recommend.server.service.recall.RecallResult;
 import com.tzld.piaoquan.recommend.server.service.recall.RecallService;
+import com.tzld.piaoquan.recommend.server.service.recall.strategy.Region24HRecallStrategy;
+import com.tzld.piaoquan.recommend.server.service.recall.strategy.RegionHRecallStrategy;
+import com.tzld.piaoquan.recommend.server.service.recall.strategy.RegionRelative24HDupRecallStrategy;
+import com.tzld.piaoquan.recommend.server.service.recall.strategy.RegionRelative24HRecallStrategy;
 import com.tzld.piaoquan.recommend.server.util.DateUtils;
 import com.tzld.piaoquan.recommend.server.util.JSONUtils;
 import lombok.extern.slf4j.Slf4j;
@@ -40,7 +44,7 @@ public class RecommendService {
     private RedisTemplate<String, String> redisTemplate;
 
 
-    private Map<String, String> ab_initial_config_map = new HashMap<>();
+    private Map<Integer, String> ab_initial_config_map = new HashMap<>();
 
     @ApolloJsonValue("ab_exp_code")
     private Map<String, Map<String, String>> abExpCodeMap = new HashMap<>();
@@ -57,15 +61,17 @@ public class RecommendService {
     private RecallService recallService;
     @Autowired
     private RankService rankService;
+    @Autowired
+    private PreViewedService preViewedService;
 
     @PostConstruct
     public void init() {
-        ab_initial_config_map.put("VLOG", "095");
-        ab_initial_config_map.put("LOVE_LIVE", "144");
-        ab_initial_config_map.put("LONG_VIDEO", "121");
-        ab_initial_config_map.put("LAO_HAO_KAN_VIDEO", "074");
-        ab_initial_config_map.put("ZUI_JING_QI", "069");
-        ab_initial_config_map.put("other", "095-1");
+        ab_initial_config_map.put(0, "095");
+        ab_initial_config_map.put(4, "144");
+        ab_initial_config_map.put(5, "121");
+        ab_initial_config_map.put(18, "074");
+        ab_initial_config_map.put(19, "069");
+        ab_initial_config_map.put(-1, "095-1");
     }
 
     public HomepageRecommendResponse homepageRecommend(HomepageRecommendRequest request) {
@@ -83,16 +89,74 @@ public class RecommendService {
 
 
         List<Video> videos = videoRecommend(request, param);
-        List<Video> result = new ArrayList<>();
-        int i = 0;
-        for (Video v : videos) {
-            result.add(v.toBuilder().setPosition(i++).build());
+
+        updateCache(request, videos);
+
+        return HomepageRecommendResponse.newBuilder()
+                .setResult(Result.newBuilder().setCode(1).setMessage("success"))
+                .addAllVideo(videos)
+                .build();
+
+    }
+
+    private void updateCache(HomepageRecommendRequest request, List<Video> videos) {
+        if (StringUtils.isNotBlank(request.getMid())
+                || CollectionUtils.isEmpty(videos)) {
+            return;
+        }
+        // 1 更新预曝光数据 过期时间 30min
+        Long[] videoIds = new Long[videos.size()];
+        for (int i = 0; i < videoIds.length; i++) {
+            videoIds[i] = videos.get(i).getVideoId();
+        }
+
+        preViewedService.updateCache(request.getAppType(), request.getMid(), videoIds);
+        updateLastVideoCache(request, videos);
+
+        // 更新流量池:本地分发数量-1
+        // redis没有这个key 也没有flowPool这个push_form
+        // updateFlowPoolCache(request, videos);
+
+        // 更新视频限流逻辑:redis没有这个key,而且代码中无引用
+
+    }
+
+    private void updateLastVideoCache(HomepageRecommendRequest request, List<Video> videos) {
+        // 2 地域小时最后一个视频
+        for (int i = videos.size() - 1; i >= 0; i--) {
+            if (videos.get(i).equals(RegionHRecallStrategy.PUSH_FORM)) {
+                redisTemplate.opsForValue().set(String.format(RegionHRecallStrategy.LAST_VIDEO_KEY_FORMAT,
+                                request.getAppType(), request.getMid()), String.valueOf(videos.get(i).getVideoId()),
+                        24, TimeUnit.HOURS);
+            }
+        }
+
+        // 3 地域24小时最后一个视频
+        for (int i = videos.size() - 1; i >= 0; i--) {
+            if (videos.get(i).equals(Region24HRecallStrategy.PUSH_FORM)) {
+                redisTemplate.opsForValue().set(String.format(Region24HRecallStrategy.LAST_VIDEO_KEY_FORMAT,
+                                request.getAppType(), request.getMid()), String.valueOf(videos.get(i).getVideoId()),
+                        24, TimeUnit.HOURS);
+            }
+        }
+
+        // 4 地域相对24小时最后一个视频
+        for (int i = videos.size() - 1; i >= 0; i--) {
+            if (videos.get(i).equals(RegionRelative24HRecallStrategy.PUSH_FORM)) {
+                redisTemplate.opsForValue().set(String.format(RegionRelative24HRecallStrategy.LAST_VIDEO_KEY_FORMAT,
+                                request.getAppType(), request.getMid()), String.valueOf(videos.get(i).getVideoId()),
+                        24, TimeUnit.HOURS);
+            }
         }
 
-        //updateCache()
-        //    update_redis_data(result=rank_result, app_type=app_type, mid=mid, top_K=top_K,
-        //                      level_weight=level_weight, flow_pool_abtest_group=flow_pool_abtest_group)
-        return null;
+        // 5 地域相对24小时最后一个视频
+        for (int i = videos.size() - 1; i >= 0; i--) {
+            if (videos.get(i).equals(RegionRelative24HDupRecallStrategy.PUSH_FORM)) {
+                redisTemplate.opsForValue().set(String.format(RegionRelative24HDupRecallStrategy.LAST_VIDEO_KEY_FORMAT,
+                                request.getAppType(), request.getMid()), String.valueOf(videos.get(i).getVideoId()),
+                        24, TimeUnit.HOURS);
+            }
+        }
     }
 
     private List<Video> videoRecommend(HomepageRecommendRequest request, HomepageRecommendParam param) {
@@ -104,15 +168,28 @@ public class RecommendService {
         rankParam.setRecallResult(recallResult);
         RankResult result = rankService.rank(rankParam);
 
+        if (result == null || CollectionUtils.isEmpty(result.getVideos())) {
+            return Collections.emptyList();
+        }
 
-        return null;
-    }
+        // 只返回size条数据
+        List<Video> videos = new ArrayList<>();
+        int size = request.getSize() < result.getVideos().size()
+                ? request.getSize()
+                : result.getVideos().size();
+
+        for (int i = 0; i < size; i++) {
+            videos.add(Video.newBuilder()
+                    .setPosition(i + 1)
+                    .setPushFrom(videos.get(i).getPushFrom())
+                    .setAbCode(videos.get(i).getAbCode())
+                    .setVideoId(videos.get(i).getVideoId())
+                    .setRovScore(videos.get(i).getRovScore())
+                    .setSortScore(videos.get(i).getRovScore())
+                    .build());
+        }
 
-    private List<Video> videoRecommendOld(HomepageRecommendRequest request, HomepageRecommendParam param) {
-        // TODO
-        RecallParam recallParam = new RecallParam();
-        recallService.recall(recallParam);
-        return null;
+        return videos;
     }
 
     private HomepageRecommendParam genHomepageRecommendParam(HomepageRecommendRequest request, int recommendType) {
@@ -125,7 +202,7 @@ public class RecommendService {
 
         String abInitialConfig = ab_initial_config_map.containsKey(request.getAppType())
                 ? ab_initial_config_map.get(request.getAppType())
-                : ab_initial_config_map.get("other");
+                : ab_initial_config_map.get(-1);
 
         Map<String, String> abExpCode = abExpCodeMap.get(abInitialConfig);
         param.setAb_code(abExpCode.get("ab_code"));

+ 101 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/ViewedService.java

@@ -0,0 +1,101 @@
+package com.tzld.piaoquan.recommend.server.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.google.common.collect.Lists;
+import com.tzld.piaoquan.recommend.server.util.JSONUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.HttpEntity;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.io.InputStream;
+import java.util.*;
+
+/**
+ * @author dyp
+ */
+@Service
+@Slf4j
+public class ViewedService {
+    private Map<Integer, List<Integer>> viewedTypesMap = new HashMap<>();
+    private List<Integer> defaultViewedTypes = Lists.newArrayList(1, 6, 7);
+
+    @Value("video.filter.url")
+    private String videoFilterUrl;
+
+    private CloseableHttpClient clients = HttpClients.createDefault();
+
+    @PostConstruct
+    public void init() {
+        viewedTypesMap.put(0, Lists.newArrayList(1, 6));
+        viewedTypesMap.put(4, Lists.newArrayList(1, 6));
+        viewedTypesMap.put(13, Lists.newArrayList(1));
+    }
+
+    public List<Long> filterViewedVideo(int appType, String mid, String uid, List<Long> videoIds) {
+        List<Integer> viewedTypes = viewedTypesMap.getOrDefault(appType, defaultViewedTypes);
+
+        CloseableHttpResponse chr = null;
+
+        try {
+
+            HttpPost post = new HttpPost(videoFilterUrl);
+            post.addHeader("Connection", "close");
+
+            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
+            nvps.add(new BasicNameValuePair("appType", String.valueOf(appType)));
+            nvps.add(new BasicNameValuePair("mid", mid));
+            nvps.add(new BasicNameValuePair("uid", uid));
+            nvps.add(new BasicNameValuePair("types", JSONUtils.toJson(viewedTypes)));
+            nvps.add(new BasicNameValuePair("videoIds", JSONUtils.toJson(videoIds)));
+
+            post.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
+
+            chr = clients.execute(post);
+            if (chr == null
+                    || chr.getStatusLine() == null
+                    || chr.getStatusLine().getStatusCode() != 200) {
+                log.info("request videoFilterUrl exception! videoFilterUrl={},statusCode={}", videoFilterUrl,
+                        chr != null && chr.getStatusLine() != null
+                                ? chr.getStatusLine().getStatusCode()
+                                : -1);
+                return Collections.emptyList();
+            }
+            HttpEntity entity = chr.getEntity();
+            if (entity == null) {
+                return Collections.emptyList();
+            }
+            InputStream is = entity.getContent();
+            if (is == null) {
+                return Collections.emptyList();
+            }
+            Map<String, List<Long>> data = JSONObject.parseObject(is.toString(), Map.class);
+            if (data.get("code") == null
+                    || !data.get("code").equals("0")) {
+                return Collections.emptyList();
+            }
+            return data.get("data");
+
+        } catch (Exception e) {
+            log.error("invoke http filterViewedVideo error", e);
+        } finally {
+            try {
+                if (chr != null) {
+                    chr.close();
+                }
+            } catch (Exception ex) {
+                log.error("close CloseableHttpResponse error", ex);
+            }
+        }
+        return Collections.emptyList();
+    }
+
+}

+ 6 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/filter/FilterParam.java

@@ -10,4 +10,10 @@ import java.util.List;
 @Data
 public class FilterParam {
     private List<Long> videoIds;
+    private String requestId;
+    private int appType;
+    private String mid;
+    private String uid;
+    private String regionCode;
+    private String shieldConfig;
 }

+ 4 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/filter/FilterResult.java

@@ -1,6 +1,8 @@
 package com.tzld.piaoquan.recommend.server.service.filter;
 
+import lombok.AllArgsConstructor;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 import java.util.List;
 
@@ -8,6 +10,8 @@ import java.util.List;
  * @author dyp
  */
 @Data
+@NoArgsConstructor
+@AllArgsConstructor
 public class FilterResult {
     private List<Long> videoIds;
 }

+ 44 - 4
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/filter/FilterService.java

@@ -1,13 +1,53 @@
 package com.tzld.piaoquan.recommend.server.service.filter;
 
-import org.springframework.stereotype.Service;
+import com.tzld.piaoquan.recommend.server.service.PreViewedService;
+import com.tzld.piaoquan.recommend.server.service.ViewedService;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * @author dyp
  */
-@Service
-public class FilterService {
+public abstract class FilterService {
+    @Autowired
+    private PreViewedService preViewedService;
+
+    @Autowired
+    private ViewedService viewedService;
+
     public FilterResult filter(FilterParam param) {
-        return null;
+        List<Long> videoIds = filterByPreViewed(param.getAppType(), param.getMid(), param.getVideoIds());
+        if (CollectionUtils.isEmpty(videoIds)) {
+            return new FilterResult(videoIds);
+        }
+        videoIds = filterByViewed(param.getAppType(), param.getMid(), param.getUid(), videoIds);
+
+        return new FilterResult(videoIds);
+    }
+
+    protected List<Long> filterByViewed(int appType, String mid, String uid, List<Long> videoIds) {
+        // TODO uid为空时,还需要过滤么?
+        if (StringUtils.isBlank(mid)) {
+            return videoIds;
+        }
+        return viewedService.filterViewedVideo(appType, mid, uid, videoIds);
+
+    }
+
+    protected List<Long> filterByPreViewed(int appType, String mid, List<Long> videoIds) {
+
+        if (StringUtils.isBlank(mid)) {
+            return videoIds;
+        }
+        Set<Long> preViewedVideoIds = preViewedService.getVideoIds(appType, mid);
+        return videoIds.stream()
+                .filter(l -> !preViewedVideoIds.contains(l))
+                .collect(Collectors.toList());
+
     }
 }

+ 14 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/filter/FlowPoolFilterService.java

@@ -0,0 +1,14 @@
+package com.tzld.piaoquan.recommend.server.service.filter;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author dyp
+ */
+@Service
+public class FlowPoolFilterService extends FilterService {
+
+}

+ 0 - 70
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/filter/FlowPoolWithLevelFilterService.java

@@ -1,70 +0,0 @@
-package com.tzld.piaoquan.recommend.server.service.filter;
-
-import com.tzld.piaoquan.recommend.server.service.FlowPoolConfigService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.stereotype.Service;
-
-import java.util.Map;
-
-/**
- * @author dyp
- */
-@Service
-public class FlowPoolWithLevelFilterService {
-    @Autowired
-    private RedisTemplate<String, String> redisTemplate;
-    @Autowired
-    private FlowPoolConfigService flowPoolConfigService;
-
-    @Autowired
-    private FilterService filterService;
-
-    public FilterResult filter(FilterParam param) {
-        FilterResult result = filterService.filter(param);
-        result.getVideoIds();
-        Map<String, Double> levelWeightMap = flowPoolConfigService.getLevelWeight();
-
-        //if self.level_weight is None:
-        //            level_weight = {'1': 1, '2': 1, '3': 1, '4': 1, '5': 1, '6': 1}
-        //        else:
-        //            level_weight = self.level_weight
-        //        level_list = [level for level in level_weight]
-        //
-        //        check_result = []
-        //        for video_id in video_ids:
-        //            video_id = int(video_id)
-        //            for flow_pool in flow_pool_mapping.get(video_id, []):
-        //                # 判断是否有本地分发记录
-        //                cur_count = get_videos_local_distribute_count(video_id=video_id, flow_pool=flow_pool)
-        //                # 无记录
-        //                if cur_count is None:
-        //                    # videos.append({'videoId': video_id, 'flowPool': flow_pool})
-        //                    continue
-        //                # 本地分发数 cur_count > 0
-        //                elif cur_count > 0:
-        //                    check_result.append((video_id, flow_pool))
-        //                # 本地分发数 cur_count <= 0,从所有的流量召回池移除,删除本地分发记录key
-        //                else:
-        //                    add_remove_log = False
-        //                    remain_count_key = f"{config_.LOCAL_DISTRIBUTE_COUNT_PREFIX}{video_id}:{flow_pool}"
-        //                    self.redis_helper.del_keys(remain_count_key)
-        //                    value = '{}-{}'.format(video_id, flow_pool)
-        //                    for item in config_.APP_TYPE:
-        //                        for level in level_list:
-        //                            flow_pool_key = f"{config_.FLOWPOOL_KEY_NAME_PREFIX_SET_LEVEL}{config_.APP_TYPE.get(item)}:{level}"
-        //                            remove_res = self.redis_helper.remove_value_from_set(key_name=flow_pool_key, values=(value, ))
-        //                            if remove_res > 0:
-        //                                add_remove_log = True
-        //                        quick_flow_pool_key = f"{config_.QUICK_FLOWPOOL_KEY_NAME_PREFIX_SET}{config_.APP_TYPE.get(item)}" \
-        //                                              f":{config_.QUICK_FLOW_POOL_ID}"
-        //                        remove_res = self.redis_helper.remove_value_from_set(key_name=quick_flow_pool_key,
-        //                                                                             values=(value, ))
-        //                        if remove_res > 0:
-        //                            add_remove_log = True
-        //                    if add_remove_log is True:
-        //                        log_.info({'tag': 'remove video_id from flow_pool', 'video_id': video_id, 'flow_pool': flow_pool})
-        //        return check_result
-        return null;
-    }
-}

+ 0 - 80
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/filter/FlowPoolWithLevelScoreFilterService.java

@@ -1,80 +0,0 @@
-package com.tzld.piaoquan.recommend.server.service.filter;
-
-import com.tzld.piaoquan.recommend.server.service.FlowPoolConfigService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.stereotype.Service;
-
-import java.util.Map;
-
-/**
- * @author dyp
- */
-@Service
-public class FlowPoolWithLevelScoreFilterService {
-    @Autowired
-    private RedisTemplate<String, String> redisTemplate;
-    @Autowired
-    private FlowPoolConfigService flowPoolConfigService;
-
-    @Autowired
-    private FilterService filterService;
-
-    public FilterResult filter(FilterParam param) {
-        FilterResult result = filterService.filter(param);
-        result.getVideoIds();
-        Map<String, Double> levelWeightMap = flowPoolConfigService.getLevelWeight();
-
-       //     def check_video_counts_new_with_level_score(self, video_ids, flow_pool_mapping):
-        //        """
-        //        检查视频剩余可分发数
-        //        :param video_ids: 视频id type-list
-        //        :param flow_pool_mapping: 视频id-流量池标记mapping, type-dict
-        //        :return: check_result, error_flag
-        //        """
-        //        # flow_pool_key = self.get_pool_redis_key('flow')
-        //        # videos = []
-        //        # level_weight = self.redis_helper.get_data_from_redis(key_name=config_.FLOWPOOL_LEVEL_WEIGHT_KEY_NAME)
-        //        # level_list = [level for level in json.loads(level_weight)]
-        //        if self.level_weight is None:
-        //            level_weight = {'1': 1, '2': 1, '3': 1, '4': 1, '5': 1, '6': 1}
-        //        else:
-        //            level_weight = self.level_weight
-        //        level_list = [level for level in level_weight]
-        //
-        //        check_result = []
-        //        for video_id in video_ids:
-        //            video_id = int(video_id)
-        //            for flow_pool in flow_pool_mapping.get(video_id, []):
-        //                # 判断是否有本地分发记录
-        //                cur_count = get_videos_local_distribute_count(video_id=video_id, flow_pool=flow_pool)
-        //                # 无记录
-        //                if cur_count is None:
-        //                    # videos.append({'videoId': video_id, 'flowPool': flow_pool})
-        //                    continue
-        //                # 本地分发数 cur_count > 0
-        //                elif cur_count > 0:
-        //                    check_result.append((video_id, flow_pool))
-        //                # 本地分发数 cur_count <= 0,从所有的流量召回池移除,删除本地分发记录key
-        //                else:
-        //                    add_remove_log = False
-        //                    remain_count_key = f"{config_.LOCAL_DISTRIBUTE_COUNT_PREFIX}{video_id}:{flow_pool}"
-        //                    self.redis_helper.del_keys(remain_count_key)
-        //                    value = '{}-{}'.format(video_id, flow_pool)
-        //                    for item in config_.APP_TYPE:
-        //                        for level in level_list:
-        //                            flow_pool_key = f"{config_.FLOWPOOL_KEY_NAME_PREFIX_SET_LEVEL_SCORE}{config_.APP_TYPE.get(item)}:{level}"
-        //                            remove_res = self.redis_helper.remove_value_from_zset(key_name=flow_pool_key, value=value)
-        //                            if remove_res > 0:
-        //                                add_remove_log = True
-        //                        quick_flow_pool_key = f"{config_.QUICK_FLOWPOOL_KEY_NAME_PREFIX}{config_.APP_TYPE.get(item)}" \
-        //                                              f":{config_.QUICK_FLOW_POOL_ID}"
-        //                        remove_res = self.redis_helper.remove_value_from_zset(key_name=quick_flow_pool_key, value=value)
-        //                        if remove_res > 0:
-        //                            add_remove_log = True
-        //                    if add_remove_log is True:
-        //                        log_.info({'tag': 'remove video_id from flow_pool', 'video_id': video_id, 'flow_pool': flow_pool})
-        //        return check_result
-        return null;
-    }
-}

+ 0 - 80
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/filter/FlowPoolWithScoreFilterService.java

@@ -1,80 +0,0 @@
-package com.tzld.piaoquan.recommend.server.service.filter;
-
-import com.tzld.piaoquan.recommend.server.service.FlowPoolConfigService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.stereotype.Service;
-
-import java.util.Map;
-
-/**
- * @author dyp
- */
-@Service
-public class FlowPoolWithScoreFilterService {
-    @Autowired
-    private RedisTemplate<String, String> redisTemplate;
-    @Autowired
-    private FlowPoolConfigService flowPoolConfigService;
-
-    @Autowired
-    private FilterService filterService;
-
-    public FilterResult filter(FilterParam param) {
-        FilterResult result = filterService.filter(param);
-        result.getVideoIds();
-        Map<String, Double> levelWeightMap = flowPoolConfigService.getLevelWeight();
-
-       //     def check_video_counts_new_with_level_score(self, video_ids, flow_pool_mapping):
-        //        """
-        //        检查视频剩余可分发数
-        //        :param video_ids: 视频id type-list
-        //        :param flow_pool_mapping: 视频id-流量池标记mapping, type-dict
-        //        :return: check_result, error_flag
-        //        """
-        //        # flow_pool_key = self.get_pool_redis_key('flow')
-        //        # videos = []
-        //        # level_weight = self.redis_helper.get_data_from_redis(key_name=config_.FLOWPOOL_LEVEL_WEIGHT_KEY_NAME)
-        //        # level_list = [level for level in json.loads(level_weight)]
-        //        if self.level_weight is None:
-        //            level_weight = {'1': 1, '2': 1, '3': 1, '4': 1, '5': 1, '6': 1}
-        //        else:
-        //            level_weight = self.level_weight
-        //        level_list = [level for level in level_weight]
-        //
-        //        check_result = []
-        //        for video_id in video_ids:
-        //            video_id = int(video_id)
-        //            for flow_pool in flow_pool_mapping.get(video_id, []):
-        //                # 判断是否有本地分发记录
-        //                cur_count = get_videos_local_distribute_count(video_id=video_id, flow_pool=flow_pool)
-        //                # 无记录
-        //                if cur_count is None:
-        //                    # videos.append({'videoId': video_id, 'flowPool': flow_pool})
-        //                    continue
-        //                # 本地分发数 cur_count > 0
-        //                elif cur_count > 0:
-        //                    check_result.append((video_id, flow_pool))
-        //                # 本地分发数 cur_count <= 0,从所有的流量召回池移除,删除本地分发记录key
-        //                else:
-        //                    add_remove_log = False
-        //                    remain_count_key = f"{config_.LOCAL_DISTRIBUTE_COUNT_PREFIX}{video_id}:{flow_pool}"
-        //                    self.redis_helper.del_keys(remain_count_key)
-        //                    value = '{}-{}'.format(video_id, flow_pool)
-        //                    for item in config_.APP_TYPE:
-        //                        for level in level_list:
-        //                            flow_pool_key = f"{config_.FLOWPOOL_KEY_NAME_PREFIX_SET_LEVEL_SCORE}{config_.APP_TYPE.get(item)}:{level}"
-        //                            remove_res = self.redis_helper.remove_value_from_zset(key_name=flow_pool_key, value=value)
-        //                            if remove_res > 0:
-        //                                add_remove_log = True
-        //                        quick_flow_pool_key = f"{config_.QUICK_FLOWPOOL_KEY_NAME_PREFIX}{config_.APP_TYPE.get(item)}" \
-        //                                              f":{config_.QUICK_FLOW_POOL_ID}"
-        //                        remove_res = self.redis_helper.remove_value_from_zset(key_name=quick_flow_pool_key, value=value)
-        //                        if remove_res > 0:
-        //                            add_remove_log = True
-        //                    if add_remove_log is True:
-        //                        log_.info({'tag': 'remove video_id from flow_pool', 'video_id': video_id, 'flow_pool': flow_pool})
-        //        return check_result
-        return null;
-    }
-}

+ 14 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/filter/RegionFilterService.java

@@ -0,0 +1,14 @@
+package com.tzld.piaoquan.recommend.server.service.filter;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author dyp
+ */
+@Service
+public class RegionFilterService extends FilterService {
+
+}

+ 1 - 20
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/filter/VideoFilterService.java

@@ -1,30 +1,11 @@
 package com.tzld.piaoquan.recommend.server.service.filter;
 
-import com.tzld.piaoquan.recommend.server.service.FlowPoolConfigService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 
-import java.util.Map;
-
 /**
  * @author dyp
  */
 @Service
-public class VideoFilterService {
-    @Autowired
-    private RedisTemplate<String, String> redisTemplate;
-
-    @Autowired
-    private FilterService filterService;
-
-    public FilterResult filter(FilterParam param) {
-        FilterResult result = filterService.filter(param);
-        result.getVideoIds();
+public class VideoFilterService extends FilterService {
 
-        //     filter_ = FilterVideos(request_id=self.request_id,
-        //                                       app_type=self.app_type, mid=self.mid, uid=self.uid, video_ids=video_ids)
-        //                filtered_viewed_videos = filter_.filter_videos_status(pool_type='normal')
-        return null;
-    }
 }

+ 0 - 4
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/RankService.java

@@ -111,10 +111,6 @@ public class RankService {
                 datas.add(rov_recall_rank.get(i));
             }
         }
-
-        if (param.getSize() < datas.size()) {
-            return new RankResult(datas.subList(0, param.getSize()));
-        }
         return new RankResult(datas);
     }
 

+ 1 - 1
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/RecallParam.java

@@ -10,7 +10,7 @@ public class RecallParam {
     private String provinceCode;
     private String cityCode;
     private String mid;
-    private String appType;
+    private int appType;
     private String dataKey;
     private String ruleKey;
     private String abCode;

+ 1 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/SpecialRegionRecallStrategy.java

@@ -100,6 +100,7 @@ public class SpecialRegionRecallStrategy implements ApplicationContextAware, Rec
             return null;
         }
 
+        // TODO 理解业务后重构,可以先召回 再过滤
         // 2. 去重
         Set<Long> videoIds = new HashSet<>();
         List<Video> results = new ArrayList<>();

+ 3 - 3
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractFlowPoolWithLevelRecallStrategy.java

@@ -4,7 +4,7 @@ import com.google.common.collect.Lists;
 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.FlowPoolWithLevelFilterService;
+import com.tzld.piaoquan.recommend.server.service.filter.FlowPoolFilterService;
 import com.tzld.piaoquan.recommend.server.service.recall.RecallParam;
 import com.tzld.piaoquan.recommend.server.service.recall.RecallStrategy;
 import org.apache.commons.collections4.CollectionUtils;
@@ -27,7 +27,7 @@ public abstract class AbstractFlowPoolWithLevelRecallStrategy implements RecallS
     protected RedisTemplate<String, String> redisTemplate;
 
     @Autowired
-    protected FlowPoolWithLevelFilterService flowPoolFilterService;
+    protected FlowPoolFilterService filterService;
 
     @Override
     public List<Video> recall(RecallParam param) {
@@ -49,7 +49,7 @@ public abstract class AbstractFlowPoolWithLevelRecallStrategy implements RecallS
 
         FilterParam filterParam = new FilterParam();
         filterParam.setVideoIds(Lists.newArrayList(videoMap.keySet()));
-        FilterResult filterResult = flowPoolFilterService.filter(filterParam);
+        FilterResult filterResult = filterService.filter(filterParam);
 
         if (filterResult != null && CollectionUtils.isNotEmpty(filterResult.getVideoIds())) {
             filterResult.getVideoIds().stream().forEach(vid -> {

+ 13 - 14
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractFlowPoolWithLevelScoreRecallStrategy.java

@@ -4,9 +4,8 @@ import com.google.common.collect.Lists;
 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.FlowPoolWithLevelScoreFilterService;
+import com.tzld.piaoquan.recommend.server.service.filter.FlowPoolFilterService;
 import com.tzld.piaoquan.recommend.server.service.recall.RecallParam;
-import com.tzld.piaoquan.recommend.server.service.recall.RecallResult;
 import com.tzld.piaoquan.recommend.server.service.recall.RecallStrategy;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.math.NumberUtils;
@@ -25,10 +24,10 @@ public abstract class AbstractFlowPoolWithLevelScoreRecallStrategy implements Re
     protected RedisTemplate<String, String> redisTemplate;
 
     @Autowired
-    protected FlowPoolWithLevelScoreFilterService flowPoolFilterService;
+    protected FlowPoolFilterService filterService;
 
     @Override
-    public List<RecallResult.RecallData> recall(RecallParam param) {
+    public List<Video> recall(RecallParam param) {
         Pair<String, String> flowPoolKeyAndLevel = flowPoolKeyAndLevel(param);
         String flowPoolKey = flowPoolKeyAndLevel.getLeft();
         String level = flowPoolKeyAndLevel.getRight();
@@ -54,19 +53,19 @@ public abstract class AbstractFlowPoolWithLevelScoreRecallStrategy implements Re
 
         FilterParam filterParam = new FilterParam();
         filterParam.setVideoIds(Lists.newArrayList(videoFlowPoolMap.keySet()));
-        FilterResult filterResult = flowPoolFilterService.filter(filterParam);
+        FilterResult filterResult = filterService.filter(filterParam);
 
         if (filterResult != null && CollectionUtils.isNotEmpty(filterResult.getVideoIds())) {
             filterResult.getVideoIds().stream().forEach(vid -> {
-                RecallResult.RecallData recallData = new RecallResult.RecallData();
-                recallData.setVideoId(vid);
-                recallData.setAbCode(param.getAbCode());
-                recallData.setRovScore(videoScoreMap.get(vid));
-                recallData.setPushFrom(pushFrom());
-                recallData.setFlowPool(videoFlowPoolMap.get(vid));
-                recallData.setFlowPoolAbtestGroup(param.getFlowPoolAbtestGroup());
-                recallData.setLevel(level);
-                results.add(recallData);
+                Video video = new Video();
+                video.setVideoId(vid);
+                video.setAbCode(param.getAbCode());
+                video.setRovScore(videoScoreMap.get(vid));
+                video.setPushFrom(pushFrom());
+                video.setFlowPool(videoFlowPoolMap.get(vid));
+                video.setFlowPoolAbtestGroup(param.getFlowPoolAbtestGroup());
+                video.setLevel(level);
+                results.add(video);
             });
         }
 

+ 3 - 3
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractFlowPoolWithScoreRecallStrategy.java

@@ -4,7 +4,7 @@ import com.google.common.collect.Lists;
 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.FlowPoolWithScoreFilterService;
+import com.tzld.piaoquan.recommend.server.service.filter.FlowPoolFilterService;
 import com.tzld.piaoquan.recommend.server.service.recall.RecallParam;
 import com.tzld.piaoquan.recommend.server.service.recall.RecallStrategy;
 import org.apache.commons.collections4.CollectionUtils;
@@ -23,7 +23,7 @@ public abstract class AbstractFlowPoolWithScoreRecallStrategy implements RecallS
     protected RedisTemplate<String, String> redisTemplate;
 
     @Autowired
-    protected FlowPoolWithScoreFilterService flowPoolFilterService;
+    protected FlowPoolFilterService filterService;
 
     @Override
     public List<Video> recall(RecallParam param) {
@@ -50,7 +50,7 @@ public abstract class AbstractFlowPoolWithScoreRecallStrategy implements RecallS
 
         FilterParam filterParam = new FilterParam();
         filterParam.setVideoIds(Lists.newArrayList(videoFlowPoolMap.keySet()));
-        FilterResult filterResult = flowPoolFilterService.filter(filterParam);
+        FilterResult filterResult = filterService.filter(filterParam);
 
         if (filterResult != null && CollectionUtils.isNotEmpty(filterResult.getVideoIds())) {
             filterResult.getVideoIds().stream().forEach(vid -> {

+ 4 - 2
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractRegionRecallStrategy.java

@@ -5,7 +5,7 @@ import com.google.common.collect.Lists;
 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.filter.RegionFilterService;
 import com.tzld.piaoquan.recommend.server.service.recall.RecallParam;
 import com.tzld.piaoquan.recommend.server.service.recall.RecallStrategy;
 import com.tzld.piaoquan.recommend.server.util.DateUtils;
@@ -26,8 +26,9 @@ public abstract class AbstractRegionRecallStrategy implements RecallStrategy {
     @Autowired
     protected RedisTemplate<String, String> redisTemplate;
 
+
     @Autowired
-    protected FilterService filterService;
+    protected RegionFilterService filterService;
 
     @Override
     public List<Video> recall(RecallParam param) {
@@ -137,6 +138,7 @@ public abstract class AbstractRegionRecallStrategy implements RecallStrategy {
         return idx;
     }
 
+    // TODO 和 推荐排序后的last更新有什么区别?
     private String updateLastVideoRecord(String recordKey, RecallParam param) {
         String currentDateStr = DateUtils.getCurrentDateStr("yyyyMMdd");
         int h = DateUtils.getCurrentHour();

+ 1 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/Region24HRecallStrategy.java

@@ -11,6 +11,7 @@ import org.springframework.stereotype.Service;
 @Service
 public class Region24HRecallStrategy extends AbstractRegionRecallStrategy {
     public static final String PUSH_FORM = "recall_pool_region_24h";
+    public static final String LAST_VIDEO_KEY_FORMAT = "recall:last:item:region:dup1:24h:%s:%s";
 
     @Override
     protected String recordKey(RecallParam param) {

+ 2 - 1
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/RegionHRecallStrategy.java

@@ -11,6 +11,7 @@ import org.springframework.stereotype.Service;
 @Service
 public class RegionHRecallStrategy extends AbstractRegionRecallStrategy {
     public static final String PUSH_FORM = "recall_pool_region_h";
+    public static final String LAST_VIDEO_KEY_FORMAT = "recall:last:item:region:h:%s:%s";
 
     @Override
     protected String recordKey(RecallParam param) {
@@ -24,7 +25,7 @@ public class RegionHRecallStrategy extends AbstractRegionRecallStrategy {
 
     @Override
     protected String lastVideoKey(RecallParam param) {
-        return String.format("recall:last:item:region:h:%s:%s", param.getAppType(), param.getMid());
+        return String.format(LAST_VIDEO_KEY_FORMAT, param.getAppType(), param.getMid());
     }
 
     @Override

+ 3 - 1
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/RegionRelative24HDupRecallStrategy.java

@@ -11,6 +11,8 @@ import org.springframework.stereotype.Service;
 @Service
 public class RegionRelative24HDupRecallStrategy extends AbstractRegionRecallStrategy {
     public static final String PUSH_FORM = "rov_recall_24h_dup";
+    public static final String LAST_VIDEO_KEY_FORMAT = "recall:last:item:region:dup3:24h:%s:%s";
+
     @Override
     protected String recordKey(RecallParam param) {
         return String.format("recall:last:record:region:dup3:24h:%s:%s", param.getAppType(), param.getMid());
@@ -23,7 +25,7 @@ public class RegionRelative24HDupRecallStrategy extends AbstractRegionRecallStra
 
     @Override
     protected String lastVideoKey(RecallParam param) {
-        return String.format("recall:last:item:region:dup3:24h:%s:%s", param.getAppType(), param.getMid());
+        return String.format(LAST_VIDEO_KEY_FORMAT, param.getAppType(), param.getMid());
     }
 
     @Override

+ 2 - 1
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/RegionRelative24HRecallStrategy.java

@@ -11,6 +11,7 @@ import org.springframework.stereotype.Service;
 @Service
 public class RegionRelative24HRecallStrategy extends AbstractRegionRecallStrategy {
     public static final String PUSH_FORM = "recall_pool_24h";
+    public static final String LAST_VIDEO_KEY_FORMAT = "recall:last:item:region:dup2:24h:%s:%s";
 
     @Override
     protected String recordKey(RecallParam param) {
@@ -24,7 +25,7 @@ public class RegionRelative24HRecallStrategy extends AbstractRegionRecallStrateg
 
     @Override
     protected String lastVideoKey(RecallParam param) {
-        return String.format("recall:last:item:region:dup2:24h:%s:%s", param.getAppType(), param.getMid());
+        return String.format(LAST_VIDEO_KEY_FORMAT, param.getAppType(), param.getMid());
     }
 
     @Override