From c03ea07dcb253e6ff1b59c403133ee72cea2f7bf Mon Sep 17 00:00:00 2001 From: "P. Reis" Date: Fri, 13 Sep 2024 10:27:12 -0300 Subject: [PATCH] feat: create getPubkeysBySearch() function and use it inside searchEvents() function --- src/controllers/api/search.ts | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/controllers/api/search.ts b/src/controllers/api/search.ts index 9bddc336..19e72cac 100644 --- a/src/controllers/api/search.ts +++ b/src/controllers/api/search.ts @@ -1,8 +1,10 @@ import { NostrEvent, NostrFilter, NSchema as n } from '@nostrify/nostrify'; import { nip19 } from 'nostr-tools'; +import { Kysely, sql } from 'kysely'; import { z } from 'zod'; import { AppController } from '@/app.ts'; +import { DittoTables } from '@/db/DittoTables.ts'; import { booleanParamSchema } from '@/schema.ts'; import { Storages } from '@/storages.ts'; import { hydrateEvents } from '@/storages/hydrate.ts'; @@ -89,9 +91,21 @@ async function searchEvents({ q, type, limit, account_id }: SearchQuery, signal: filter.authors = [account_id]; } + const filter2: NostrFilter = { + kinds: [0], + limit, + }; + if (type === 'accounts') { + const kysely = await Storages.kysely(); + + const pubkeys = await getPubkeysBySearch(kysely, { q, limit }); + + filter2.authors = pubkeys; // if pubkeys is empty the filter 2 will be discarded + } + const store = await Storages.search(); - return store.query([filter], { signal }) + return store.query([filter, filter2], { signal }) .then((events) => hydrateEvents({ events, store, signal })); } @@ -170,4 +184,16 @@ async function getLookupFilters({ q, type, resolve }: SearchQuery, signal: Abort return []; } -export { searchController }; +/** Get pubkeys whose name and NIP-05 is similar to 'q' */ +async function getPubkeysBySearch(kysely: Kysely, { q, limit }: Pick) { + const pubkeys = (await sql` + SELECT *, word_similarity(${q}, search) AS sml + FROM author_search + WHERE ${q} % search + ORDER BY sml DESC, search LIMIT ${limit} + `.execute(kysely)).rows.map((row) => (row as { pubkey: string }).pubkey); + + return pubkeys; +} + +export { getPubkeysBySearch, searchController };