mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 11:29:46 +00:00
Improve performance of account search
This commit is contained in:
parent
7d8e5e676c
commit
379953a8cb
2 changed files with 34 additions and 33 deletions
|
|
@ -119,6 +119,7 @@ const accountSearchQuerySchema = z.object({
|
||||||
const accountSearchController: AppController = async (c) => {
|
const accountSearchController: AppController = async (c) => {
|
||||||
const { signal } = c.req.raw;
|
const { signal } = c.req.raw;
|
||||||
const { limit } = c.get('pagination');
|
const { limit } = c.get('pagination');
|
||||||
|
|
||||||
const kysely = await Storages.kysely();
|
const kysely = await Storages.kysely();
|
||||||
const viewerPubkey = await c.get('signer')?.getPublicKey();
|
const viewerPubkey = await c.get('signer')?.getPublicKey();
|
||||||
|
|
||||||
|
|
@ -136,27 +137,22 @@ const accountSearchController: AppController = async (c) => {
|
||||||
|
|
||||||
if (!event && lookup) {
|
if (!event && lookup) {
|
||||||
const pubkey = await lookupPubkey(lookup);
|
const pubkey = await lookupPubkey(lookup);
|
||||||
return c.json(pubkey ? [await accountFromPubkey(pubkey)] : []);
|
return c.json(pubkey ? [accountFromPubkey(pubkey)] : []);
|
||||||
}
|
}
|
||||||
|
|
||||||
const followedPubkeys: Set<string> = viewerPubkey ? await getFollowedPubkeys(viewerPubkey) : new Set();
|
const events: NostrEvent[] = [];
|
||||||
const pubkeys = Array.from(await getPubkeysBySearch(kysely, { q: query, limit, offset: 0, followedPubkeys }));
|
|
||||||
|
|
||||||
let events = event ? [event] : await store.query([{ kinds: [0], authors: pubkeys, limit }], {
|
if (event) {
|
||||||
signal,
|
events.push(event);
|
||||||
});
|
} else {
|
||||||
|
const following = viewerPubkey ? await getFollowedPubkeys(viewerPubkey) : new Set<string>();
|
||||||
if (!event) {
|
const authors = [...await getPubkeysBySearch(kysely, { q: query, limit, offset: 0, following })];
|
||||||
events = pubkeys
|
const profiles = await store.query([{ kinds: [0], authors, limit }], { signal });
|
||||||
.map((pubkey) => events.find((event) => event.pubkey === pubkey))
|
events.push(...profiles);
|
||||||
.filter((event) => !!event);
|
|
||||||
}
|
}
|
||||||
const accounts = await hydrateEvents({ events, store, signal }).then(
|
|
||||||
(events) =>
|
const accounts = await hydrateEvents({ events, store, signal })
|
||||||
Promise.all(
|
.then((events) => events.map((event) => renderAccount(event)));
|
||||||
events.map((event) => renderAccount(event)),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
return c.json(accounts);
|
return c.json(accounts);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -5,30 +5,35 @@ import { DittoTables } from '@/db/DittoTables.ts';
|
||||||
/** Get pubkeys whose name and NIP-05 is similar to 'q' */
|
/** Get pubkeys whose name and NIP-05 is similar to 'q' */
|
||||||
export async function getPubkeysBySearch(
|
export async function getPubkeysBySearch(
|
||||||
kysely: Kysely<DittoTables>,
|
kysely: Kysely<DittoTables>,
|
||||||
opts: { q: string; limit: number; offset: number; followedPubkeys: Set<string> },
|
opts: { q: string; limit: number; offset: number; following: Set<string> },
|
||||||
): Promise<Set<string>> {
|
): Promise<Set<string>> {
|
||||||
const { q, limit, followedPubkeys, offset } = opts;
|
const { q, limit, following, offset } = opts;
|
||||||
|
|
||||||
let query = kysely
|
const pubkeys = new Set<string>();
|
||||||
|
|
||||||
|
const query = kysely
|
||||||
.selectFrom('author_stats')
|
.selectFrom('author_stats')
|
||||||
.select((eb) => [
|
.select('pubkey')
|
||||||
'pubkey',
|
.where('search', sql`%>`, q)
|
||||||
'search',
|
.orderBy('followers_count desc')
|
||||||
eb.fn('word_similarity', [sql`${q}`, 'search']).as('sml'),
|
|
||||||
])
|
|
||||||
.where(() => sql`${q} <% search`)
|
|
||||||
.orderBy(['followers_count desc'])
|
|
||||||
.orderBy(['sml desc', 'search'])
|
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
.offset(offset);
|
.offset(offset);
|
||||||
|
|
||||||
const pubkeys = new Set((await query.execute()).map(({ pubkey }) => pubkey));
|
if (following.size) {
|
||||||
|
const authorsQuery = query.where('pubkey', 'in', [...following]);
|
||||||
|
|
||||||
if (followedPubkeys.size > 0) {
|
for (const { pubkey } of await authorsQuery.execute()) {
|
||||||
query = query.where('pubkey', 'in', [...followedPubkeys]);
|
pubkeys.add(pubkey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const followingPubkeys = new Set((await query.execute()).map(({ pubkey }) => pubkey));
|
if (pubkeys.size >= limit) {
|
||||||
|
return pubkeys;
|
||||||
|
}
|
||||||
|
|
||||||
return new Set(Array.from(followingPubkeys.union(pubkeys)));
|
for (const { pubkey } of await query.execute()) {
|
||||||
|
pubkeys.add(pubkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pubkeys;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue