From ab7a0e06c7e77590532f839671127980f1f00920 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Wed, 12 Feb 2025 15:21:09 -0600 Subject: [PATCH] Add a top_authors materialized view --- src/cron.ts | 18 +++++++++++++++--- src/db/DittoTables.ts | 2 ++ src/db/migrations/049_author_stats_sorted.ts | 13 +++++++++++++ src/utils/search.ts | 3 +-- 4 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 src/db/migrations/049_author_stats_sorted.ts diff --git a/src/cron.ts b/src/cron.ts index 6994561e..ba8a18d5 100644 --- a/src/cron.ts +++ b/src/cron.ts @@ -1,6 +1,13 @@ -import { updateTrendingLinks } from '@/trends.ts'; -import { updateTrendingHashtags } from '@/trends.ts'; -import { updateTrendingEvents, updateTrendingPubkeys, updateTrendingZappedEvents } from '@/trends.ts'; +import { sql } from 'kysely'; + +import { Storages } from '@/storages.ts'; +import { + updateTrendingEvents, + updateTrendingHashtags, + updateTrendingLinks, + updateTrendingPubkeys, + updateTrendingZappedEvents, +} from '@/trends.ts'; /** Start cron jobs for the application. */ export function cron() { @@ -9,4 +16,9 @@ export function cron() { Deno.cron('update trending events', '15 * * * *', updateTrendingEvents); Deno.cron('update trending hashtags', '30 * * * *', updateTrendingHashtags); Deno.cron('update trending links', '45 * * * *', updateTrendingLinks); + + Deno.cron('refresh top authors', '20 * * * *', async () => { + const kysely = await Storages.kysely(); + await sql`refresh materialized view top_authors`.execute(kysely); + }); } diff --git a/src/db/DittoTables.ts b/src/db/DittoTables.ts index ea326724..5a7e4c73 100644 --- a/src/db/DittoTables.ts +++ b/src/db/DittoTables.ts @@ -9,6 +9,8 @@ export interface DittoTables extends NPostgresSchema { event_stats: EventStatsRow; event_zaps: EventZapRow; push_subscriptions: PushSubscriptionRow; + /** This is a materialized view of `author_stats` pre-sorted by followers_count. */ + top_authors: Pick; } interface AuthorStatsRow { diff --git a/src/db/migrations/049_author_stats_sorted.ts b/src/db/migrations/049_author_stats_sorted.ts new file mode 100644 index 00000000..425cc7c8 --- /dev/null +++ b/src/db/migrations/049_author_stats_sorted.ts @@ -0,0 +1,13 @@ +import { Kysely } from 'kysely'; + +export async function up(db: Kysely): Promise { + await db.schema + .createView('top_authors') + .materialized() + .as(db.selectFrom('author_stats').select(['pubkey', 'followers_count', 'search']).orderBy('followers_count desc')) + .execute(); +} + +export async function down(db: Kysely): Promise { + await db.schema.dropView('top_authors').execute(); +} diff --git a/src/utils/search.ts b/src/utils/search.ts index 205ee740..e41cd413 100644 --- a/src/utils/search.ts +++ b/src/utils/search.ts @@ -12,10 +12,9 @@ export async function getPubkeysBySearch( const pubkeys = new Set(); const query = kysely - .selectFrom('author_stats') + .selectFrom('top_authors') .select('pubkey') .where('search', sql`%>`, q) - .orderBy('followers_count desc') .limit(limit) .offset(offset);