blok Beliebt: po ogledih zadnjih 7 dni namesto skupnega stevca, da se dejansko menja (parameter ?days=)

This commit is contained in:
2026-08-30 09:43:29 +02:00
parent ed47a05bff
commit 7f7c5e05d1
2 changed files with 30 additions and 4 deletions
+2 -1
View File
@@ -261,7 +261,8 @@ export async function registerRoutes(
app.get("/api/articles/popular", async (req, res) => {
const limit = parseInt(req.query.limit as string) || 6;
const articles = await storage.getPopularArticles(limit);
const days = parseInt(req.query.days as string) || 7;
const articles = await storage.getPopularArticles(limit, days);
res.json(articles);
});
+28 -3
View File
@@ -1,6 +1,6 @@
import { type Article, type InsertArticle, articles, articleViews, type InsertPushSubscription, type PushSubscription, pushSubscriptions } from "@shared/schema";
import { db } from "./db";
import { eq, desc, sql, count, and } from "drizzle-orm";
import { eq, desc, sql, count, and, gte, inArray } from "drizzle-orm";
import crypto from "crypto";
export interface IStorage {
@@ -40,8 +40,33 @@ export class DatabaseStorage implements IStorage {
return db.select().from(articles).orderBy(desc(articles.publishedAt)).limit(9);
}
async getPopularArticles(limit: number): Promise<Article[]> {
return db.select().from(articles).orderBy(desc(articles.views)).limit(limit);
// "Beliebt" mora dejansko rotirati: steje ogled v zadnjih `days` dneh, ne
// stevec od zacetka. Ta je namrec za stare uspesnice tako visok, da se blok
// nikoli ne premakne. Ce svezih ogledov ni dovolj, dopolnimo po skupnem stevcu.
async getPopularArticles(limit: number, days: number = 7): Promise<Article[]> {
const since = new Date(Date.now() - days * 86400000);
const recent = await db
.select({ id: articleViews.articleId, n: count() })
.from(articleViews)
.where(gte(articleViews.viewedAt, since))
.groupBy(articleViews.articleId)
.orderBy(desc(count()))
.limit(limit * 3);
const ids = recent.map((r) => r.id);
let out: Article[] = [];
if (ids.length) {
const rows = await db.select().from(articles).where(inArray(articles.id, ids));
const byId = new Map(rows.map((a) => [a.id, a]));
out = ids.map((i) => byId.get(i)).filter(Boolean) as Article[];
}
if (out.length < limit) {
const fill = await db.select().from(articles).orderBy(desc(articles.views)).limit(limit * 2);
const have = new Set(out.map((a) => a.id));
for (const a of fill) {
if (!have.has(a.id)) { out.push(a); have.add(a.id); }
}
}
return out.slice(0, limit);
}
async getArticlesByCategory(category: string): Promise<Article[]> {