feat: make trends fast again

remove previous JOIN, now if a language is set, it will do '''query.where('trends.value', 'in', languagesIds);''', which is faster than a JOIN
This commit is contained in:
P. Reis 2024-10-01 13:58:08 -03:00
parent b549cdef53
commit d8b2c057b0

View file

@ -1,5 +1,5 @@
import { LanguageCode } from 'iso-639-1'; import { LanguageCode } from 'iso-639-1';
import { NostrFilter } from '@nostrify/nostrify'; import { NostrEvent, NostrFilter } from '@nostrify/nostrify';
import { Stickynotes } from '@soapbox/stickynotes'; import { Stickynotes } from '@soapbox/stickynotes';
import { Kysely, sql } from 'kysely'; import { Kysely, sql } from 'kysely';
@ -20,8 +20,8 @@ export async function getTrendingTagValues(
tagNames: string[], tagNames: string[],
/** Filter of eligible events. */ /** Filter of eligible events. */
filter: NostrFilter, filter: NostrFilter,
/** Only return trending events of 'language' */ /** Results must be inside 'languagesIds' */
language?: LanguageCode, languagesIds?: string[],
): Promise<{ value: string; authors: number; uses: number }[]> { ): Promise<{ value: string; authors: number; uses: number }[]> {
let query = kysely.with('trends', (db) => { let query = kysely.with('trends', (db) => {
let query = db let query = db
@ -54,14 +54,13 @@ export async function getTrendingTagValues(
return query; return query;
}) })
.selectFrom(['trends']) .selectFrom(['trends'])
.innerJoin('nostr_events', 'trends.value', 'nostr_events.id')
.select(['value', 'authors', 'uses']); .select(['value', 'authors', 'uses']);
if (language) { if (languagesIds) {
query = query.where('nostr_events.language', '=', language); query = query.where('trends.value', 'in', languagesIds);
} }
query = query.orderBy('authors desc'); query = query.orderBy('authors desc').orderBy('uses desc');
if (typeof filter.limit === 'number') { if (typeof filter.limit === 'number') {
query = query.limit(filter.limit); query = query.limit(filter.limit);
@ -95,13 +94,24 @@ export async function updateTrendingTags(
const tagNames = aliases ? [tagName, ...aliases] : [tagName]; const tagNames = aliases ? [tagName, ...aliases] : [tagName];
let languagesIds: NostrEvent['id'][] = [];
if (language) {
const result = (await kysely.selectFrom('nostr_events')
.select('id')
.where('language', '=', language)
.where('nostr_events.created_at', '>=', yesterday)
.where('nostr_events.created_at', '<=', now)
.execute()).map((event) => event.id);
languagesIds = result;
}
try { try {
const trends = await getTrendingTagValues(kysely, tagNames, { const trends = await getTrendingTagValues(kysely, tagNames, {
kinds, kinds,
since: yesterday, since: yesterday,
until: now, until: now,
limit, limit,
}, language); }, languagesIds);
if (!trends.length) { if (!trends.length) {
console.info(`No trending ${l} found. Skipping.`); console.info(`No trending ${l} found. Skipping.`);
@ -110,19 +120,14 @@ export async function updateTrendingTags(
const signer = new AdminSigner(); const signer = new AdminSigner();
const tags = [
['L', 'pub.ditto.trends'],
['l', l, 'pub.ditto.trends'],
...trends.map(({ value, authors, uses }) => [tagName, value, extra, authors.toString(), uses.toString()]),
];
if (language) {
tags.push(['lang', language]);
}
const label = await signer.signEvent({ const label = await signer.signEvent({
kind: 1985, kind: 1985,
content: '', content: '',
tags, tags: [
['L', 'pub.ditto.trends'],
['l', languagesIds.length ? `${l}.${language}` : l, 'pub.ditto.trends'],
...trends.map(({ value, authors, uses }) => [tagName, value, extra, authors.toString(), uses.toString()]),
],
created_at: Math.floor(Date.now() / 1000), created_at: Math.floor(Date.now() / 1000),
}); });
@ -145,7 +150,7 @@ export function updateTrendingZappedEvents(): Promise<void> {
/** Update trending events. */ /** Update trending events. */
export async function updateTrendingEvents(): Promise<void> { export async function updateTrendingEvents(): Promise<void> {
const languages = Conf.trendLanguages; const languages = Conf.preferredLanguages;
if (!languages) return updateTrendingTags('#e', 'e', [1, 6, 7, 9735], 40, Conf.relay, ['q']); if (!languages) return updateTrendingTags('#e', 'e', [1, 6, 7, 9735], 40, Conf.relay, ['q']);
const promise: Promise<void>[] = []; const promise: Promise<void>[] = [];