diff --git a/backend/src/api/database-migration.ts b/backend/src/api/database-migration.ts index 5cbd78d40..1d6f10a2c 100644 --- a/backend/src/api/database-migration.ts +++ b/backend/src/api/database-migration.ts @@ -4,7 +4,7 @@ import logger from '../logger'; import { Common } from './common'; class DatabaseMigration { - private static currentVersion = 38; + private static currentVersion = 39; private queryTimeout = 120000; private statisticsAddedIndexed = false; private uniqueLogs: string[] = []; @@ -337,6 +337,11 @@ class DatabaseMigration { await this.$executeQuery('ALTER TABLE `lightning_stats` CHANGE `added` `added` timestamp NULL'); await this.$executeQuery('ALTER TABLE `node_stats` CHANGE `added` `added` timestamp NULL'); } + + if (databaseSchemaVersion < 39 && isBitcoin === true) { + await this.$executeQuery('ALTER TABLE `nodes` ADD alias_search TEXT NULL DEFAULT NULL AFTER `alias`'); + await this.$executeQuery('ALTER TABLE nodes ADD FULLTEXT(alias_search)'); + } } /** diff --git a/backend/src/api/explorer/nodes.api.ts b/backend/src/api/explorer/nodes.api.ts index 474a0cabf..379df4213 100644 --- a/backend/src/api/explorer/nodes.api.ts +++ b/backend/src/api/explorer/nodes.api.ts @@ -259,9 +259,10 @@ class NodesApi { public async $searchNodeByPublicKeyOrAlias(search: string) { try { - const searchStripped = search.replace('%', '') + '%'; - const query = `SELECT nodes.public_key, nodes.alias, node_stats.capacity FROM nodes LEFT JOIN node_stats ON node_stats.public_key = nodes.public_key WHERE nodes.public_key LIKE ? OR nodes.alias LIKE ? GROUP BY nodes.public_key ORDER BY node_stats.capacity DESC LIMIT 10`; - const [rows]: any = await DB.query(query, [searchStripped, searchStripped]); + const publicKeySearch = search.replace('%', '') + '%'; + const aliasSearch = search.replace(/[-_.]/g, ' ').replace(/[^a-zA-Z ]/g, '').split(' ').map((search) => '+' + search + '*').join(' '); + const query = `SELECT nodes.public_key, nodes.alias, node_stats.capacity FROM nodes LEFT JOIN node_stats ON node_stats.public_key = nodes.public_key WHERE nodes.public_key LIKE ? OR MATCH nodes.alias_search AGAINST (? IN BOOLEAN MODE) GROUP BY nodes.public_key ORDER BY node_stats.capacity DESC LIMIT 10`; + const [rows]: any = await DB.query(query, [publicKeySearch, aliasSearch]); return rows; } catch (e) { logger.err('$searchNodeByPublicKeyOrAlias error: ' + (e instanceof Error ? e.message : e)); @@ -501,21 +502,24 @@ class NodesApi { first_seen, updated_at, alias, + alias_search, color, sockets, status ) - VALUES (?, NOW(), FROM_UNIXTIME(?), ?, ?, ?, 1) - ON DUPLICATE KEY UPDATE updated_at = FROM_UNIXTIME(?), alias = ?, color = ?, sockets = ?, status = 1`; + VALUES (?, NOW(), FROM_UNIXTIME(?), ?, ?, ?, ?, 1) + ON DUPLICATE KEY UPDATE updated_at = FROM_UNIXTIME(?), alias = ?, alias_search = ?, color = ?, sockets = ?, status = 1`; await DB.query(query, [ node.pub_key, node.last_update, node.alias, + this.aliasToSearchText(node.alias), node.color, sockets, node.last_update, node.alias, + this.aliasToSearchText(node.alias), node.color, sockets, ]); @@ -549,6 +553,10 @@ class NodesApi { logger.err('$setNodesInactive() error: ' + (e instanceof Error ? e.message : e)); } } + + private aliasToSearchText(str: string): string { + return str.replace(/[-_.]/g, ' ').replace(/[^a-zA-Z ]/g, ''); + } } export default new NodesApi();