瀏覽代碼

add abtest: 518

liqian 1 年之前
父節點
當前提交
dbf47ba6ba
共有 3 個文件被更改,包括 164 次插入23 次删除
  1. 16 1
      config.py
  2. 32 11
      recommend.py
  3. 116 11
      video_recall.py

+ 16 - 1
config.py

@@ -192,6 +192,7 @@ class BaseConfig(object):
             'abtest_508': 60093,
             'abtest_510': 60094,
             'abtest_514': 60095,
+            'abtest_518': 60096,
         },  # 地域分组小时级规则实验
 
         'rank_by_24h': {
@@ -560,6 +561,11 @@ class BaseConfig(object):
             'data_key': 'data10', 'rule_key': 'rule27', 'rank_key_prefix': 'rank:score8:',
             'ab_code': AB_CODE['region_rank_by_h'].get('abtest_514')
         },  # simrecall+融合+backrate指数加权_2 + rank_score8
+        '518': {
+            'data_key': 'data10', 'rule_key': 'rule7',
+            'h_data_key': 'data10', 'h_rule_key': 'rule1',
+            'ab_code': AB_CODE['region_rank_by_h'].get('abtest_518'),
+        },  # simrecall+融合+不区分地域小时级列表作为单路召回(不做离线去重)
 
     }
 
@@ -645,7 +651,8 @@ class BaseConfig(object):
         'u2i_tag_recall':'u2i_tag_recall', #u2i_tag_recall
         'u2u2i_recall':'u2u2i_recall', #u2u2i_recall,
         'return_video_recall': 'return_video_recall',  # return_video_recall
-        'u2i_tag_play_recall': 'u2i_tag_play_recall', # u2i_tag_recall
+        'u2i_tag_play_recall': 'u2i_tag_play_recall',  # u2i_tag_recall
+        'rov_recall_h_h_without_dup': 'rov_recall_h_h_without_dup',  # 不区分地域小时级更新列表(不做离线去重)
     }
 
     # category id mapping
@@ -726,6 +733,14 @@ class BaseConfig(object):
     # 记录 mid-上一次在dup3 48h更新列表中对应的位置key 中数据所属(date,h),完整格式:recall:last:record:region:dup2:48h:{appType}:{mid}
     RECORD_KEY_NAME_PREFIX_LAST_VIDEO_REGION_DUP3_48H = 'recall:last:record:region:dup3:48h:'
 
+    # 用户上一次在 不分地域小时级(不做离线去重) 更新列表中对应的位置 redis key前缀,完整key格式:recall:last:item:h:{appType}:{mid}
+    LAST_VIDEO_FROM_H_PREFIX = 'recall:last:item:h:'
+    # 记录 mid-上一次在 不分地域小时级(不做离线去重) 更新列表中对应的位置key 中数据所属(date,h),完整格式:recall:last:record:h:{appType}:{mid}
+    RECORD_KEY_NAME_PREFIX_LAST_VIDEO_H = 'recall:last:record:h:'
+    # 小程序不分地域小时级(不做离线去重)更新结果 存放 redis key前缀,
+    # 完整格式:recall:item:score:h:{h_data_key}:{h_rule_key}:{date}:{h}
+    RECALL_KEY_NAME_PREFIX_BY_H_H = 'recall:item:score:h:'
+
     # # 小时级视频状态不符合推荐要求的列表 redis key,完整格式:com.weiqu.video.filter.h.item.{rule_key}
     # H_VIDEO_FILER = 'com.weiqu.video.filter.h.item.'
 

+ 32 - 11
recommend.py

@@ -458,7 +458,7 @@ def video_old_recommend(request_id, mid, uid, size, top_K, flow_pool_P, app_type
                     expire_time=24*3600, ab_code=config_.AB_CODE['initial'], rule_key='', data_key='',
                     no_op_flag=False, old_video_index=-1, video_id=None, params=None, rule_key_30day=None,
                     shield_config=None, env_dict=None, level_weight=None, flow_pool_abtest_group=None,
-                        rank_key_prefix=None):
+                        rank_key_prefix=None, h_data_key=None, h_rule_key=None):
     """
     首页线上推荐逻辑
     :param request_id: request_id
@@ -487,7 +487,8 @@ def video_old_recommend(request_id, mid, uid, size, top_K, flow_pool_P, app_type
                              app_type=app_type, mid=mid, uid=uid, ab_code=ab_code,
                              client_info=client_info, rule_key=rule_key, data_key=data_key, no_op_flag=no_op_flag,
                              params=params, rule_key_30day=rule_key_30day, shield_config=shield_config,
-                             video_id=video_id, level_weight=level_weight)
+                             video_id=video_id, level_weight=level_weight,
+                             h_data_key=h_data_key, h_rule_key=h_rule_key)
 
     exp_config = pool_recall.get_sort_ab_codel_config()
     # 60054 全量: simrecall+融合排序
@@ -525,7 +526,8 @@ def video_old_recommend(request_id, mid, uid, size, top_K, flow_pool_P, app_type
     if ab_code == 60054 or ab_code == 60066 or ab_code == 60072 or ab_code == 60073 or ab_code == 60074 \
             or ab_code == 60075 or ab_code == 60076 or ab_code == 60077 or ab_code == 60078 or ab_code == 60079 \
             or ab_code == 60087 or ab_code == 60088 or ab_code == 60089 or ab_code == 60090 \
-            or ab_code == 60091 or ab_code == 60092 or ab_code == 60093 or ab_code == 60094 or ab_code == 60095:
+            or ab_code == 60091 or ab_code == 60092 or ab_code == 60093 or ab_code == 60094 or ab_code == 60095 \
+            or ab_code == 60096:
         t.append(gevent.spawn(pool_recall.get_sim_hot_item_reall_filter))
     elif ab_code == 60056 or ab_code == 60071:
         t.append(gevent.spawn(pool_recall.get_sim_hot_item_reall_filter))
@@ -550,7 +552,8 @@ def video_old_recommend(request_id, mid, uid, size, top_K, flow_pool_P, app_type
     if ab_code == 60054 or ab_code == 60066 or ab_code == 60072 or ab_code == 60073 or ab_code == 60074 \
             or ab_code == 60075 or ab_code == 60076 or ab_code == 60077 or ab_code == 60078 or ab_code == 60079 \
             or ab_code == 60087 or ab_code == 60088 or ab_code == 60089 or ab_code == 60090 \
-            or ab_code == 60091 or ab_code == 60092 or ab_code == 60093 or ab_code == 60094 or ab_code == 60095:
+            or ab_code == 60091 or ab_code == 60092 or ab_code == 60093 or ab_code == 60094 or ab_code == 60095 \
+            or ab_code == 60096:
         rov_pool_recall = []
         if len(recall_result_list) >= 2:
             region_recall = recall_result_list[0]
@@ -1092,6 +1095,14 @@ def update_redis_data(result, app_type, mid, top_K, expire_time=24*3600, level_w
                 redis_helper.set_data_to_redis(key_name=last_video_key, value=rov_recall_24h_dup3_video[-1],
                                                expire_time=expire_time)
 
+            # 将此次获取的 不分地域小时级数据列表(不做离线去重)中的视频id同步刷新到redis中,方便下次快速定位到召回位置
+            rov_recall_h_h_without_dup_video = [item['videoId'] for item in result[:top_K]
+                                                if item['pushFrom'] == config_.PUSH_FROM['rov_recall_h_h_without_dup']]
+            if len(rov_recall_h_h_without_dup_video) > 0:
+                last_video_key = f'{config_.LAST_VIDEO_FROM_H_PREFIX}{app_type}:{mid}'
+                redis_helper.set_data_to_redis(key_name=last_video_key, value=rov_recall_h_h_without_dup_video[-1],
+                                               expire_time=expire_time)
+
             # # 将此次获取的 相对48h筛选数据列表 中的视频id同步刷新到redis中,方便下次快速定位到召回位置
             # rov_recall_48h_dup2_video = [item['videoId'] for item in result[:top_K]
             #                              if item['pushFrom'] == config_.PUSH_FROM['rov_recall_48h']]
@@ -1486,6 +1497,8 @@ def get_recommend_params(recommend_type, ab_exp_info, ab_info_data, mid, app_typ
     rule_key_30day = param.get('30day_rule_key')
     shield_config = config_.SHIELD_CONFIG
     rank_key_prefix = 'rank:score1:'
+    h_rule_key = param.get('h_rule_key')
+    h_data_key = param.get('h_data_key')
 
     # 默认使用 095 实验的配置
     # ab_code = config_.AB_EXP_CODE['095'].get('ab_code')
@@ -1601,6 +1614,8 @@ def get_recommend_params(recommend_type, ab_exp_info, ab_info_data, mid, app_typ
                     rule_key_30day = param.get('30day_rule_key')
                     shield_config = param.get('shield_config', config_.SHIELD_CONFIG)
                     rank_key_prefix = param.get('rank_key_prefix', 'rank:score1:')
+                    h_rule_key = param.get('h_rule_key')
+                    h_data_key = param.get('h_data_key')
                     break
 
             """
@@ -1900,7 +1915,7 @@ def get_recommend_params(recommend_type, ab_exp_info, ab_info_data, mid, app_typ
     # log_.info(f"flow_pool_id_choice: {flow_pool_id_choice}, flow_pool_abtest_group: {flow_pool_abtest_group}")
 
     return top_K, flow_pool_P, ab_code, rule_key, data_key, expire_time, no_op_flag, old_video_index, rule_key_30day, \
-           shield_config, flow_pool_abtest_group, rank_key_prefix
+           shield_config, flow_pool_abtest_group, rank_key_prefix, h_data_key, h_rule_key
 
 
 def video_homepage_recommend(request_id, mid, uid, size, app_type, algo_type,
@@ -1969,7 +1984,8 @@ def video_homepage_recommend(request_id, mid, uid, size, app_type, algo_type,
 
     # 普通mid推荐处理
     top_K, flow_pool_P, ab_code, rule_key, data_key, expire_time, \
-    no_op_flag, old_video_index, rule_key_30day, shield_config, flow_pool_abtest_group, rank_key_prefix = \
+    no_op_flag, old_video_index, rule_key_30day, shield_config, flow_pool_abtest_group, rank_key_prefix, \
+    h_data_key, h_rule_key = \
         get_recommend_params(recommend_type=0, ab_exp_info=ab_exp_info, ab_info_data=ab_info_data, mid=mid,
                              app_type=app_type, flow_pool_abtest_config=flow_pool_abtest_config)
     # log_.info({
@@ -2005,7 +2021,8 @@ def video_homepage_recommend(request_id, mid, uid, size, app_type, algo_type,
             or ab_code == 60078 or ab_code == 60079 or ab_code == 60080 or ab_code == 60081 or ab_code == 60082\
             or ab_code == 60083 or ab_code == 60084 or ab_code == 60085 or ab_code == 60086 \
             or ab_code == 60087 or ab_code == 60088 or ab_code == 60089 or ab_code == 60090 \
-            or ab_code == 60091 or ab_code == 60092 or ab_code == 60093 or ab_code == 60094 or ab_code == 60095:
+            or ab_code == 60091 or ab_code == 60092 or ab_code == 60093 or ab_code == 60094 or ab_code == 60095 \
+            or ab_code == 60096:
         result, fea_info = video_old_recommend(request_id=request_id, mid=mid, uid=uid, app_type=app_type, size=size,
                                                top_K=top_K, flow_pool_P=flow_pool_P, algo_type='',
                                                client_info=client_info, ab_code=ab_code, expire_time=expire_time,
@@ -2014,7 +2031,8 @@ def video_homepage_recommend(request_id, mid, uid, size, app_type, algo_type,
                                                rule_key_30day=rule_key_30day, shield_config=shield_config,
                                                env_dict=env_dict, level_weight=level_weight,
                                                flow_pool_abtest_group=flow_pool_abtest_group,
-                                               rank_key_prefix=rank_key_prefix)
+                                               rank_key_prefix=rank_key_prefix,
+                                               h_data_key=h_data_key, h_rule_key=h_rule_key)
         recommend_result['fea_info'] = fea_info
     else:
         result = video_recommend(request_id=request_id, mid=mid, uid=uid, app_type=app_type, size=size, top_K=top_K,
@@ -2099,7 +2117,8 @@ def video_relevant_recommend(request_id, video_id, mid, uid, size, app_type, ab_
 
     # 普通mid推荐处理
     top_K, flow_pool_P, ab_code, rule_key, data_key, expire_time, \
-    no_op_flag, old_video_index, rule_key_30day, shield_config, flow_pool_abtest_group, rank_key_prefix = \
+    no_op_flag, old_video_index, rule_key_30day, shield_config, flow_pool_abtest_group, rank_key_prefix, \
+    h_data_key, h_rule_key = \
         get_recommend_params(recommend_type=1, ab_exp_info=ab_exp_info, ab_info_data=ab_info_data, page_type=page_type,
                              mid=mid, app_type=app_type, flow_pool_abtest_config=flow_pool_abtest_config)
     # log_.info({
@@ -2130,7 +2149,8 @@ def video_relevant_recommend(request_id, video_id, mid, uid, size, app_type, ab_
             or ab_code == 60078 or ab_code == 60079 or ab_code == 60080 or ab_code == 60081 or ab_code == 60082 \
             or ab_code == 60083 or ab_code == 60084 or ab_code == 60085 or ab_code == 60086 \
             or ab_code == 60087 or ab_code == 60088 or ab_code == 60089 or ab_code == 60090 \
-            or ab_code == 60091 or ab_code == 60092 or ab_code == 60093 or ab_code == 60094 or ab_code == 60095:
+            or ab_code == 60091 or ab_code == 60092 or ab_code == 60093 or ab_code == 60094 or ab_code == 60095 \
+            or ab_code == 60096:
         result, fea_info = video_old_recommend(request_id=request_id, mid=mid, uid=uid, app_type=app_type, size=size,
                                                top_K=top_K, flow_pool_P=flow_pool_P, algo_type='',
                                                client_info=client_info, ab_code=ab_code, expire_time=expire_time,
@@ -2139,7 +2159,8 @@ def video_relevant_recommend(request_id, video_id, mid, uid, size, app_type, ab_
                                                rule_key_30day=rule_key_30day, shield_config=shield_config,
                                                env_dict=env_dict, level_weight=level_weight,
                                                flow_pool_abtest_group=flow_pool_abtest_group,
-                                               rank_key_prefix=rank_key_prefix)
+                                               rank_key_prefix=rank_key_prefix,
+                                               h_data_key=h_data_key, h_rule_key=h_rule_key)
         recommend_result['fea_info'] = fea_info
     else:
         result = video_recommend(request_id=request_id, mid=mid, uid=uid, app_type=app_type, size=size, top_K=top_K,

+ 116 - 11
video_recall.py

@@ -18,7 +18,7 @@ class PoolRecall(object):
     """召回"""
     def __init__(self, request_id, app_type, client_info=None, mid='', uid='', ab_code='',
                  rule_key='', data_key='', no_op_flag=False, params=None, rule_key_30day=None, shield_config=None,
-                 video_id=None, level_weight=None):
+                 video_id=None, level_weight=None, h_data_key=None, h_rule_key=None):
         """
         初始化
         :param request_id: request_id
@@ -43,6 +43,8 @@ class PoolRecall(object):
         self.shield_config = shield_config
         self.level_weight = level_weight
         self.redis_helper = RedisHelper(params=params)
+        self.h_data_key = data_key
+        self.h_rule_key = h_rule_key
 
     def copy_redis_zset_data(self, from_key_name, to_key_name):
         # 获取from_key_name中的数据
@@ -2096,7 +2098,19 @@ class PoolRecall(object):
         # })
         #print("recall_num:", recall_num)
         #print("recall_result:", recall_result[:recall_num])
-        return recall_result[:recall_num]
+
+        if self.h_data_key is None or self.h_rule_key is None:
+            return recall_result[:recall_num]
+        else:
+            # 补充不区分地域小时级结果(不做离线去重)
+            recall_h_h_result = self.recall_h(province_code=region_code, size=size, expire_time=expire_time)
+            # 去重
+            for video in recall_h_h_result:
+                video_id = video.get('videoId')
+                if video_id not in now_video_ids:
+                    recall_result.append(video)
+                    now_video_ids.append(video_id)
+            return recall_result
 
     def rov_pool_recall_with_region(self, size=4, expire_time=24*3600):
         """召回池召回视频"""
@@ -2535,12 +2549,16 @@ class PoolRecall(object):
 
         return recall_result[:size]
 
-    def update_last_video_record(self, record_key, pool_key_prefix, province_code):
+    def update_last_video_record(self, record_key, pool_key_prefix, province_code, data_key=None, rule_key=None):
+        if data_key is None or rule_key is None:
+            data_key = self.data_key
+            rule_key = self.rule_key
         # 判断当前小时的小时级列表是否更新
         now_date = datetime.today()
         h = datetime.now().hour
         now_dt = datetime.strftime(now_date, '%Y%m%d')
-        now_pool_recall_key = f"{pool_key_prefix}{province_code}:{self.data_key}:{self.rule_key}:{now_dt}:{h}"
+        # now_pool_recall_key = f"{pool_key_prefix}{province_code}:{self.data_key}:{self.rule_key}:{now_dt}:{h}"
+        now_pool_recall_key = f"{pool_key_prefix}{province_code}:{data_key}:{rule_key}:{now_dt}:{h}"
         if self.redis_helper.key_exists(key_name=now_pool_recall_key):
             value = {'date': now_dt, 'h': h}
             self.redis_helper.set_data_to_redis(key_name=record_key, value=str(value), expire_time=2 * 3600)
@@ -2551,7 +2569,8 @@ class PoolRecall(object):
             else:
                 redis_dt = now_dt
                 redis_h = h - 1
-            now_pool_recall_key = f"{pool_key_prefix}{province_code}:{self.data_key}:{self.rule_key}:{redis_dt}:{redis_h}"
+            # now_pool_recall_key = f"{pool_key_prefix}{province_code}:{self.data_key}:{self.rule_key}:{redis_dt}:{redis_h}"
+            now_pool_recall_key = f"{pool_key_prefix}{province_code}:{data_key}:{rule_key}:{redis_dt}:{redis_h}"
             value = {'date': redis_dt, 'h': redis_h}
             self.redis_helper.set_data_to_redis(key_name=record_key, value=str(value), expire_time=2 * 3600)
         return now_pool_recall_key
@@ -2574,7 +2593,11 @@ class PoolRecall(object):
             idx = 0
         return idx
 
-    def get_last_recommend_video_idx(self, province_code, record_key_prefix, pool_key_prefix, last_video_key_prefix):
+    def get_last_recommend_video_idx(self, province_code, record_key_prefix, pool_key_prefix, last_video_key_prefix,
+                                     data_key=None, rule_key=None):
+        if data_key is None or rule_key is None:
+            data_key = self.data_key
+            rule_key = self.rule_key
         # 判断mid对应上一次视频位置 时间记录
         record_key = f"{record_key_prefix}{self.app_type}:{self.mid}"
         last_video_key = f'{last_video_key_prefix}{self.app_type}:{self.mid}'
@@ -2584,7 +2607,8 @@ class PoolRecall(object):
             self.redis_helper.del_keys(key_name=last_video_key)
             idx = 0
             pool_recall_key = self.update_last_video_record(record_key=record_key, pool_key_prefix=pool_key_prefix,
-                                                            province_code=province_code)
+                                                            province_code=province_code,
+                                                            data_key=data_key, rule_key=rule_key)
         else:
             # ###### 记录key存在,判断date, h
             now_date = datetime.today()
@@ -2596,11 +2620,14 @@ class PoolRecall(object):
             now_dt = datetime.strftime(now_date, '%Y%m%d')
             if record_dt == now_dt and int(record_h) == h:
                 # 已获取当前小时数据
-                pool_recall_key = f"{pool_key_prefix}{province_code}:{self.data_key}:{self.rule_key}:{now_dt}:{h}"
+                # pool_recall_key = f"{pool_key_prefix}{province_code}:{self.data_key}:{self.rule_key}:{now_dt}:{h}"
+                pool_recall_key = f"{pool_key_prefix}{province_code}:{data_key}:{rule_key}:{now_dt}:{h}"
                 idx = self.get_video_idx(pool_recall_key=pool_recall_key, last_video_key=last_video_key)
             elif (record_dt == now_dt and h-int(record_h) == 1) or (h == 0 and int(record_h) == 23):
                 # 记录的h - 当前h = 1,判断当前h数据是否已更新
-                now_pool_recall_key = f"{pool_key_prefix}{province_code}:{self.data_key}:{self.rule_key}:{now_dt}:{h}"
+                # now_pool_recall_key = f"{pool_key_prefix}{province_code}:{self.data_key}:{self.rule_key}:{now_dt}:{h}"
+                now_pool_recall_key = f"{pool_key_prefix}{province_code}:{data_key}:{rule_key}:{now_dt}:{h}"
+
                 if self.redis_helper.key_exists(key_name=now_pool_recall_key):
                     new_record = {'date': now_dt, 'h': h}
                     self.redis_helper.set_data_to_redis(key_name=record_key, value=str(new_record), expire_time=2*3600)
@@ -2608,13 +2635,16 @@ class PoolRecall(object):
                     self.redis_helper.del_keys(key_name=last_video_key)
                     pool_recall_key = now_pool_recall_key
                 else:
-                    pool_recall_key = f"{pool_key_prefix}{province_code}:{self.data_key}:{self.rule_key}:{record_dt}:{record_h}"
+                    # pool_recall_key = f"{pool_key_prefix}{province_code}:{self.data_key}:{self.rule_key}:{record_dt}:{record_h}"
+                    pool_recall_key = f"{pool_key_prefix}{province_code}:{data_key}:{rule_key}:{record_dt}:{record_h}"
+
                     idx = self.get_video_idx(pool_recall_key=pool_recall_key, last_video_key=last_video_key)
             else:
                 idx = 0
                 self.redis_helper.del_keys(key_name=last_video_key)
                 pool_recall_key = self.update_last_video_record(record_key=record_key, pool_key_prefix=pool_key_prefix,
-                                                                province_code=province_code)
+                                                                province_code=province_code,
+                                                                data_key=data_key, rule_key=rule_key)
 
         return pool_recall_key, idx
 
@@ -2759,6 +2789,81 @@ class PoolRecall(object):
         # })
         return pool_recall_result[:size]
 
+    def recall_h(self, province_code, size=4, expire_time=2*3600):
+        """
+        从不区分地域小时级列表 更新结果中获取视频
+        :param size: 获取视频个数
+        :param expire_time: 末位视频记录redis过期时间
+        :return:
+        """
+        # 不分地域小时级列表
+        # mid对应上一次视频位置 时间记录
+        record_key_prefix = config_.RECORD_KEY_NAME_PREFIX_LAST_VIDEO_H
+        # 视频列表
+        pool_key_prefix = config_.RECALL_KEY_NAME_PREFIX_BY_H_H
+        # mid对应上一次视频记录
+        last_video_key_prefix = config_.LAST_VIDEO_FROM_H_PREFIX
+        push_from = config_.PUSH_FROM['rov_recall_h_h_without_dup']
+
+        # 获取相关redis key, 用户上一次在rov召回池对应的位置
+        pool_key, idx = self.get_last_recommend_video_idx(province_code=province_code,
+                                                          record_key_prefix=record_key_prefix,
+                                                          pool_key_prefix=pool_key_prefix,
+                                                          last_video_key_prefix=last_video_key_prefix,
+                                                          data_key=self.h_data_key,
+                                                          rule_key=self.h_rule_key)
+        if not pool_key:
+            return []
+        recall_data = []
+        pool_recall_result = []
+        # 每次获取的视频数
+        get_size = size * 5
+        # 记录获取频次
+        freq = 0
+        while len(pool_recall_result) < size:
+            freq += 1
+            if freq > config_.MAX_FREQ_FROM_ROV_POOL:
+                break
+            # 获取数据
+            data = self.redis_helper.get_data_zset_with_index(key_name=pool_key,
+                                                              start=idx, end=idx + get_size - 1,
+                                                              with_scores=True)
+            if not data:
+                break
+            recall_data.extend(data)
+            # 获取视频id,并转换类型为int,并存储为key-value{videoId: score}
+            video_ids = []
+            video_score = {}
+            for value in data:
+                video_id = int(value[0])
+                video_ids.append(video_id)
+                video_score[video_id] = value[1]
+            # 过滤
+            filter_ = FilterVideos(request_id=self.request_id,
+                                   app_type=self.app_type, mid=self.mid, uid=self.uid, video_ids=video_ids)
+            ge = gevent.spawn(filter_.filter_videos, pool_type='normal',
+                              region_code=province_code, shield_config=self.shield_config)
+            ge.join()
+            filtered_result = ge.get()
+
+            if filtered_result:
+                # 添加视频源参数 pushFrom, abCode
+                temp_result = [{'videoId': int(item), 'rovScore': video_score[int(item)],
+                                'pushFrom': push_from, 'abCode': self.ab_code}
+                               for item in filtered_result if video_score.get(int(item)) is not None]
+                pool_recall_result.extend(temp_result)
+            idx += get_size
+
+        pool_recall_result.sort(key=lambda x: x.get('rovScore', 0), reverse=True)
+
+        if len(recall_data) > 0 and len(pool_recall_result) == 0 and self.mid:
+            # 召回数据不为空 & 过滤后结果为空 & 位于实验组 & mid不为空时,更新召回获取的末位视频id记录到定位的key中
+            last_video_key = f'{last_video_key_prefix}{self.app_type}:{self.mid}'
+            self.redis_helper.set_data_to_redis(key_name=last_video_key, value=recall_data[-1][0],
+                                                expire_time=expire_time)
+
+        return pool_recall_result
+
     def update_last_video_record_by_day(self, record_key, pool_key_prefix, expire_time):
         # 判断当前日期的小时级列表是否更新
         now_date = datetime.today()