shikeying
2022-09-26 fd03e31f173ad9c52b15a30a9127e2b6a468538d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
package com.iplatform.recvideo.support;
 
import com.iplatform.model.po.Rc_video_t1;
import com.iplatform.model.po.Rc_video_t2;
import com.iplatform.model.po.Rc_video_user;
import com.iplatform.recvideo.Constants;
import com.iplatform.recvideo.SimilarExecutor;
import com.iplatform.recvideo.SimilarVideoInfo;
import com.iplatform.recvideo.SimilarVideoOrder;
import com.iplatform.recvideo.SimilarVideoUser;
import com.iplatform.recvideo.SimilarVideoUserOrder;
import com.iplatform.recvideo.VideoFolderInfo;
import com.iplatform.recvideo.service.VideoExecutorServiceImpl;
import com.iplatform.recvideo.util.PythonInvokeUtils;
import com.walker.infrastructure.utils.DateUtils;
import com.walker.infrastructure.utils.NumberGenerator;
import com.walker.infrastructure.utils.StringUtils;
import org.springframework.web.client.RestTemplate;
 
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
 
public class DefaultSimilarExecutor extends SimilarExecutor {
 
    private RestTemplate restTemplate;
 
    // python AI 服务地址前缀
    private String remoteUrl;
 
    private VideoExecutorServiceImpl videoExecutorService = null;
 
    public void setVideoExecutorService(VideoExecutorServiceImpl videoExecutorService) {
        this.videoExecutorService = videoExecutorService;
    }
 
    public void setRemoteUrl(String remoteUrl) {
        this.remoteUrl = remoteUrl;
    }
 
    public void setRestTemplate(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }
 
    @Override
    protected boolean pythonLoadVideoDone(String batchId, String batchFolder) {
        return this.videoExecutorService.queryLoadVideoDone(batchFolder);
    }
 
    @Override
    protected String requestStartPythonLoadVideo(String batchId) throws Exception {
        logger.info("开始请求python服务:" + Constants.AI_SERVICE_VIDEO_LOAD);
        return null;
    }
 
    @Override
    protected List<Rc_video_t1> acquirePythonSearchSimilarOnce(String srcVideoId, String imagePath, String topN) throws Exception {
        String url = this.remoteUrl + Constants.AI_SERVICE_VIDEO_SEARCH;
        return PythonInvokeUtils.acquireImageSearchResult(srcVideoId, imagePath, topN, url, this.restTemplate);
    }
 
    @Override
    protected void writeRcVideoT1(List<Rc_video_t1> list, String srcImageId) {
        // 删除 distance == 0 的,这个是自身视频信息(推荐的要排除自己)
        Rc_video_t1 e = null;
        for(Iterator<Rc_video_t1> it = list.iterator(); it.hasNext();){
            e = it.next();
            if(e.getDistance().doubleValue() == 0){
                it.remove();
            }
        }
        this.videoExecutorService.execBatchInsertVideoT1(list, srcImageId);
        logger.debug("成功写入集合'Rc_video_t1':" + list.size());
    }
 
    @Override
    protected void writeRcVideoT2(VideoFolderInfo videoFolderInfo, String batchId) {
        logger.debug("正在写入'Rc_video_t2',原始视频:" + videoFolderInfo.getVideoId());
        List<Rc_video_t1> list = this.videoExecutorService.queryVideoT_1List(videoFolderInfo.getVideoId());
        if(StringUtils.isEmptyList(list)){
            logger.warn("writeRcVideoT2: Rc_video_t1检索结果为空,无法继续写入'Rc_video_t2'");
            return;
        }
        SimilarVideoOrder similarVideoOrder = new SimilarVideoOrder(list);
        List<SimilarVideoInfo> similarVideoInfoList = similarVideoOrder.calculateOrder();
        List<Rc_video_t2> video2List = this.toRcVideoT2List(videoFolderInfo.getVideoId(), similarVideoInfoList, batchId);
        if(video2List == null){
            logger.warn("writeRcVideoT2(): similarVideoInfoList为空,不能执行, srcVideoId = " + videoFolderInfo.getVideoId());
            return;
        }
        this.videoExecutorService.execBatchInsertVideoT2(video2List, videoFolderInfo.getVideoId());
    }
 
    @Override
    protected void writeRcVideoUser(String batchId, List<String> recVideoIdList) {
        logger.info("正在写入一次用户推荐视频数据, batchId = " + batchId);
        List<Map<String, Object>> batchUserVideoList = this.videoExecutorService.queryBatchUserVideoList(batchId);
        if(StringUtils.isEmptyList(batchUserVideoList)){
            logger.error("未找到批次用户视频记录,无法更新用户推荐视频数据,batchId = " + batchId);
            return;
        }
        List<Rc_video_t2> video2List = this.videoExecutorService.queryVideoT_2List(batchId);
        if(StringUtils.isEmptyList(video2List)){
            logger.warn("从表'rc_video_t2'未加载到批次视频结果记录,无法继续写入用户推荐视频'rc_video_user'");
            return;
        }
 
        // 原始视频ID与用户关系
        Map<String, Long> srcVideoIdUserCache = new HashMap<>();
        for(Map<String, Object> m : batchUserVideoList){
            srcVideoIdUserCache.put(m.get("src_video_id").toString(), Long.parseLong(m.get("user_id").toString()));
        }
 
        // 推荐视频ID与用户关系
        Map<String, Long> videoIdUserCache = new HashMap<>();
        Long userId = null;
        for(Rc_video_t2 e : video2List){
            userId = srcVideoIdUserCache.get(e.getSrc_video_id());
            if(userId == null){
                throw new IllegalArgumentException("推荐视频的原始视频未找到对应用户,src_video = " + e.getSrc_video_id() + ", rec_video = " + e.getSim_video_id());
            }
            videoIdUserCache.put(e.getSim_video_id(), userId);
        }
 
        SimilarVideoUserOrder similarVideoUserOrder = new SimilarVideoUserOrder(videoIdUserCache, video2List);
        List<SimilarVideoUser> similarVideoUserList = similarVideoUserOrder.calculateOrder();
        List<Rc_video_user> videoUserList = this.toRcVideoUserList(similarVideoUserList);
        if(videoUserList == null){
            logger.warn("writeRcVideoUser(): similarVideoUserList,不能执行, batchId = " + batchId);
            return;
        }
 
        // 用户推荐视频记录,需要更新,如果不存在才写入。
        // 注意:这里暂时不更新,全部写入,这样用户推荐表中会存在较多重复数据,后续要添加定时任务清除重复数据即可。
        this.videoExecutorService.execBatchInsertVideoUser(videoUserList, batchId);
        logger.debug("批次任务状态已更新成功! " + batchId);
    }
 
    private List<Rc_video_user> toRcVideoUserList(List<SimilarVideoUser> similarVideoUserList){
        if(StringUtils.isEmptyList(similarVideoUserList)){
            return null;
        }
        List<Rc_video_user> resultList = new ArrayList<>(similarVideoUserList.size());
        Rc_video_user rc_video_t2 = null;
        for(SimilarVideoUser e : similarVideoUserList){
            rc_video_t2 = new Rc_video_user(NumberGenerator.getLongSequenceNumber());
            rc_video_t2.setCreate_time(Long.parseLong(DateUtils.getDateTimeSecondForShow()));
            rc_video_t2.setUser_id(e.getUserId());
            rc_video_t2.setVideo_id(e.getRecommendVideoId());
            rc_video_t2.setScore(e.getScore());
            resultList.add(rc_video_t2);
        }
        return resultList;
    }
 
    private List<Rc_video_t2> toRcVideoT2List(String srcVideoId
            , List<SimilarVideoInfo> similarVideoInfoList, String batchId){
        if(StringUtils.isEmptyList(similarVideoInfoList)){
            return null;
        }
        List<Rc_video_t2> resultList = new ArrayList<>(similarVideoInfoList.size());
        Rc_video_t2 rc_video_t2 = null;
        for(SimilarVideoInfo e : similarVideoInfoList){
            rc_video_t2 = new Rc_video_t2(NumberGenerator.getLongSequenceId());
            rc_video_t2.setSrc_video_id(srcVideoId);
            rc_video_t2.setSim_video_id(e.getId());
            rc_video_t2.setScore(e.getScore());
            rc_video_t2.setBatch_id(batchId);
            resultList.add(rc_video_t2);
        }
        return resultList;
    }
}