mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 11:29:46 +00:00
Merge branch 'domain-search-perf' into 'main'
EventsDB: fix domain search performance (also allow searching by multiple languages/domains) See merge request soapbox-pub/ditto!497
This commit is contained in:
commit
ee68fbad48
1 changed files with 40 additions and 13 deletions
|
|
@ -153,22 +153,16 @@ class EventsDB extends NPostgres {
|
||||||
search: tokens.filter((t) => typeof t === 'string').join(' '),
|
search: tokens.filter((t) => typeof t === 'string').join(' '),
|
||||||
}) as SelectQueryBuilder<DittoTables, 'nostr_events', Pick<DittoTables['nostr_events'], keyof NostrEvent>>;
|
}) as SelectQueryBuilder<DittoTables, 'nostr_events', Pick<DittoTables['nostr_events'], keyof NostrEvent>>;
|
||||||
|
|
||||||
const data = tokens.filter((t) => typeof t === 'object').reduce(
|
const languages = new Set<string>();
|
||||||
(acc, t) => acc.set(t.key, t.value),
|
|
||||||
new Map<string, string>(),
|
|
||||||
);
|
|
||||||
|
|
||||||
const domain = data.get('domain');
|
for (const token of tokens) {
|
||||||
const language = data.get('language');
|
if (typeof token === 'object' && token.key === 'language') {
|
||||||
|
languages.add(token.value);
|
||||||
if (domain) {
|
}
|
||||||
query = query
|
|
||||||
.innerJoin('pubkey_domains', 'nostr_events.pubkey', 'pubkey_domains.pubkey')
|
|
||||||
.where('pubkey_domains.domain', '=', domain);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (language) {
|
if (languages.size) {
|
||||||
query = query.where('language', '=', language);
|
query = query.where('language', 'in', [...languages]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
|
|
@ -288,6 +282,39 @@ class EventsDB extends NPostgres {
|
||||||
filters = structuredClone(filters);
|
filters = structuredClone(filters);
|
||||||
|
|
||||||
for (const filter of filters) {
|
for (const filter of filters) {
|
||||||
|
if (filter.search) {
|
||||||
|
const tokens = NIP50.parseInput(filter.search);
|
||||||
|
|
||||||
|
const domains = new Set<string>();
|
||||||
|
|
||||||
|
for (const token of tokens) {
|
||||||
|
if (typeof token === 'object' && token.key === 'domain') {
|
||||||
|
domains.add(token.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (domains.size) {
|
||||||
|
const query = this.opts.kysely
|
||||||
|
.selectFrom('pubkey_domains')
|
||||||
|
.select('pubkey')
|
||||||
|
.where('domain', 'in', [...domains]);
|
||||||
|
|
||||||
|
if (filter.authors) {
|
||||||
|
query.where('pubkey', 'in', filter.authors);
|
||||||
|
}
|
||||||
|
|
||||||
|
const pubkeys = await query.execute().then((rows) => rows.map((row) => row.pubkey));
|
||||||
|
|
||||||
|
filter.authors = pubkeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-serialize the search string without the domain key. :facepalm:
|
||||||
|
filter.search = tokens
|
||||||
|
.filter((t) => typeof t === 'object' && t.key !== 'domain')
|
||||||
|
.map((t) => typeof t === 'object' ? `${t.key}:${t.value}` : t)
|
||||||
|
.join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
if (filter.kinds) {
|
if (filter.kinds) {
|
||||||
// Ephemeral events are not stored, so don't bother querying for them.
|
// Ephemeral events are not stored, so don't bother querying for them.
|
||||||
// If this results in an empty kinds array, NDatabase will remove the filter before querying and return no results.
|
// If this results in an empty kinds array, NDatabase will remove the filter before querying and return no results.
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue