JS实现的在线推荐逻辑

时间:2022-05-25 06:21:45

import _ from 'lodash';
import cfg from '../cfg/cfg';
import {Response} from '../shared/lib/response';
import {RecDB} from '../lib/mongo.js';
import {timed} from '../utils/metrics';

let config = cfg.recommend.mongo;

// getUserPrefer 获得用户看过和不喜欢看的视频 userprefer
let getUserPrefer = async (opts) => {
opts = opts || {};
let macId = opts.macId;
let resList = [];
// let res = await RecDB.read({
// query: {
// mac: macId
// },
// collection: 'userprefer'
// });
let read = timed('personalRec.readUserPreferVideos', async () => {
let doRead = await RecDB.read({
query: {
mac: macId
},
collection: 'userprefer'
});
return doRead;
});
let res = await read();
_.forEach(res, (val) => {
let notLike = [];
let seen = [];
if (!val.isNotLike) {
notLike = _.split(val.isNotLike, ':');
}
if (!val.isSeen) {
seen = _.split(val.isSeen, ':');
}
resList = _.concat(notLike, seen);
});
return resList;
};
let getUserRecords = async(opts) => {
opts = opts || {};
let macId = opts.macId;
if (!macId) {
return {
total: 0,
data: []
};
}// userrecord
let readRecords = timed('personRec.readRecords', async() => {
let doRead = await RecDB.findOne({
query: {
mac: opts.macId
},
collection: 'temp'
});
return doRead;
});
let res = await readRecords();
let result = res ? res.vv : null;
result = result || [];
let videos = _.map(result, 'id');
return videos;
};
// 获取在线用户推荐数据
let getRealtimeVideos = async(opts) => {
opts = opts || {};
let videoId = opts.videoId;
if (!videoId) {
return {
total: 0,
data: []
};
}
let read = timed('personRec.realtimeVideos', async() => {
let doRead = await RecDB.findOne({
query: {
videoId: opts.videoId,
group: opts.group
},
collection: 'related'
});
return doRead;
});
let res = await read();
res = res ? res.result : null;
//console.log(JSON.stringify(res));
res = res || [];
let videos = _.chain(res)
.forEach((val) => {
val.group = opts.group;
val.type = 'realtime';
})
.value();
return videos;
};

let getPersonalVideos = async (opts) => {
opts = opts || {};
let videos = [];
let page = opts.page;
let pageSize = opts.pageSize;
let userPrefers = await getUserPrefer({macId: opts.macId });
let record = await getUserRecords({macId: opts.macId });
let realtime = [];
for (let video of record) {
//console.log(video)
let append = await getRealtimeVideos({videoId: video, group: 'B' });
console.log(JSON.stringify(append));
realtime = _.concat(realtime, append);
}
userPrefers = _.concat(userPrefers, record);
let real = _.chain(realtime).map((val) => {
let temp = {
id: val.id,
group: val.group,
type: val.type
};
// console.log(JSON.stringify(temp));
return temp;
}).filter(val => !_.includes(userPrefers, val.videoId))
.value();
let group = opts.group || 'a';
// 获取分组对应的 collection
let collectionName = _.get(config.groupMapping, group);
if (!collectionName) {
return {
total: 0,
data: []
};
}
// let res = await RecDB.read({
// query: {
// mac: opts.macId
// },
// collection: collectionName
// });
let readVideos = timed('personalRec.readPersonalVideos', async () => {
let doRead = await RecDB.read({
query: {
mac: opts.macId
},
collection: collectionName
});
return doRead;
});
let res = await readVideos();
_.forEach(res, (doc) => {
_.forEach(_.split(doc.result, ','), (val) => {
let arr = _.split(val, ':');
if (!_.includes(userPrefers, arr[0])) {
let result = {
id: arr[0],
alg: _.concat(arr.slice(1, 4), group).join(':')
};
videos = _.concat(videos, result);
}
});
});
//console.log(JSON.stringify(real));
videos = _.uniq(_.concat(real, videos), 'id');
return {
total: videos.length,
data: videos.slice((page - 1) * pageSize, pageSize)
};
};

let realtimeRecHandler = async (ctx) => {
let query = ctx.query;
// let page = query.page;
let page = parseInt(query.page, 10) || 1;
let pageSize = parseInt(query.pageSize, 10) || 10;
let macId = query.macId;
let group = query.group;
let res = await getPersonalVideos({
page,
pageSize,
macId,
group
});
let pageCount = _.ceil(_.divide(res.total, pageSize));
return new Response({
data: {
page,
pageSize,
pageCount,
macId,
total: res.total,
videos: res.data
}
});
};

export {
realtimeRecHandler,
};