Files
2026-07-26 18:25:37 +09:00

41 lines
1.8 KiB
JavaScript

import { Brackets } from "typeorm";
import { Followings, Notes } from "../../../models/index.js";
import { Cache } from "../../../misc/cache.js";
import { apiLogger } from "../logger.js";
export const cache = new Cache("homeTlQueryData", 60 * 60 * 24);
const cutoff = 250; // 250 posts in the last 7 days, constant determined by comparing benchmarks for cutoff values between 100 and 2500
const logger = apiLogger.createSubLogger("heuristics");
export async function generateFollowingQuery(q, me) {
const followingQuery = Followings.createQueryBuilder("following").select("following.followeeId").where("following.followerId = :meId");
const heuristic = await cache.fetch(me.id, async ()=>{
let curr = new Date();
let prev = new Date();
prev.setDate(prev.getDate() - 7);
return Notes.createQueryBuilder('note').where(`note.createdAt > :prev`, {
prev
}).andWhere(`note.createdAt < :curr`, {
curr
}).andWhere(new Brackets((qb)=>{
qb.where(`note.userId IN (${followingQuery.getQuery()})`);
qb.orWhere(`note.userId = :meId`, {
meId: me.id
});
})).getCount().then((res)=>{
logger.info(`Calculating heuristics for user ${me.id} took ${new Date().getTime() - curr.getTime()}ms`);
return res;
});
});
const shouldUseUnion = heuristic < cutoff;
q.andWhere(new Brackets((qb)=>{
if (shouldUseUnion) {
qb.where(`note.userId = ANY(array(${followingQuery.getQuery()} UNION ALL VALUES (:meId)))`);
} else {
qb.where(`note.userId = :meId`);
qb.orWhere(`note.userId IN (${followingQuery.getQuery()})`);
}
}));
q.setParameters({
meId: me.id
});
}