1
0
mirror of https://github.com/hotomoe/hotomoe synced 2024-12-05 10:18:09 +09:00

Improve hashtag trend detection

This commit is contained in:
syuilo 2018-06-12 01:41:17 +09:00
parent 91db24fcfc
commit 90337adbbc

View File

@ -1,13 +1,23 @@
import Note from '../../../../models/note'; import Note from '../../../../models/note';
/*
a分間のユニーク投稿数が今からa分前b分前の間のユニーク投稿数のn倍以上5
稿稿稿稿1
*/
const rangeA = 1000 * 60 * 10; // 10分
const rangeB = 1000 * 60 * 60; // 1時間
const coefficient = 2; // 「n倍」の部分
/** /**
* Get trends of hashtags * Get trends of hashtags
*/ */
module.exports = () => new Promise(async (res, rej) => { module.exports = () => new Promise(async (res, rej) => {
//#region 1. 直近Aの内に投稿されたハッシュタグ(とユーザーのペア)を集計
const data = await Note.aggregate([{ const data = await Note.aggregate([{
$match: { $match: {
createdAt: { createdAt: {
$gt: new Date(Date.now() - 1000 * 60 * 60) $gt: new Date(Date.now() - rangeA)
}, },
tags: { tags: {
$exists: true, $exists: true,
@ -26,6 +36,7 @@ module.exports = () => new Promise(async (res, rej) => {
userId: any; userId: any;
} }
}>; }>;
//#endregion
if (data.length == 0) { if (data.length == 0) {
return res([]); return res([]);
@ -33,6 +44,7 @@ module.exports = () => new Promise(async (res, rej) => {
const tags = []; const tags = [];
// カウント
data.map(x => x._id).forEach(x => { data.map(x => x._id).forEach(x => {
const i = tags.findIndex(tag => tag.name == x.tags); const i = tags.findIndex(tag => tag.name == x.tags);
if (i != -1) { if (i != -1) {
@ -45,11 +57,31 @@ module.exports = () => new Promise(async (res, rej) => {
} }
}); });
const hots = tags //#region 2. 1で取得したそれぞれのタグについて、「直近a分間のユニーク投稿数が今からa分前今からb分前の間のユニーク投稿数のn倍以上」かどうかを判定する
const hotsPromises = tags.map(async tag => {
const passedCount = (await Note.distinct('userId', {
tags: tag,
createdAt: {
$lt: new Date(Date.now() - rangeA),
$gt: new Date(Date.now() - rangeB)
}
}) as any).length;
if (passedCount > (tag.count * coefficient)) {
return tag;
} else {
return null;
}
});
//#endregion
const hots = (await Promise.all(hotsPromises))
.filter(x => x != null)
.sort((a, b) => b.count - a.count) .sort((a, b) => b.count - a.count)
.map(tag => tag.name) .map(tag => tag.name)
.slice(0, 5); .slice(0, 5);
//#region 2で話題と判定されたタグそれぞれについて過去の投稿数グラフを取得する
const countPromises: Array<Promise<any[]>> = []; const countPromises: Array<Promise<any[]>> = [];
const range = 20; const range = 20;
@ -75,6 +107,7 @@ module.exports = () => new Promise(async (res, rej) => {
$gt: new Date(Date.now() - (interval * range)) $gt: new Date(Date.now() - (interval * range))
} }
}))); })));
//#endregion
const stats = hots.map((tag, i) => ({ const stats = hots.map((tag, i) => ({
tag, tag,