From 00f048d3ae82fbea62510b7a23a473de656db8d7 Mon Sep 17 00:00:00 2001 From: Sarjuuk Date: Mon, 9 Feb 2026 09:53:08 +0100 Subject: [PATCH] Search/Fixup * readd regular indizes for name cols. There are cases where entities are named in a way that does not work with FT indizes. ex. "XT:9" is two tokens "XT", "9" which are too short to be indexed. * additionally to FT search also exact match col to search string. --- includes/components/filter.class.php | 27 +++++---- includes/components/search.class.php | 11 ++-- setup/sql/01-db_structure.sql | 80 ++++++++++++++++-------- setup/sql/updates/1770626911_01.sql | 91 ++++++++++++++++++++++++++++ 4 files changed, 168 insertions(+), 41 deletions(-) create mode 100644 setup/sql/updates/1770626911_01.sql diff --git a/includes/components/filter.class.php b/includes/components/filter.class.php index 94369daf..3208a862 100644 --- a/includes/components/filter.class.php +++ b/includes/components/filter.class.php @@ -622,8 +622,8 @@ abstract class Filter if (Lang::getLocale()->isLogographic() && !Cfg::get('LOGOGRAPHIC_FT_SEARCH')) return $this->tokenizeString($fields, $string, $exact, $allowShort); - $string = trim(preg_replace(self::PATTERN_FT, ' ', $string)); - if (!$string) + $ftString = trim(preg_replace(self::PATTERN_FT, ' ', $string)); + if (!$ftString) return []; // always allow sub 3 chars for logographic locales @@ -631,7 +631,7 @@ abstract class Filter $allowShort = true; $sub = []; - $tokens = $exact ? [$string] : array_filter(explode(' ', $string)); + $tokens = $exact ? [$ftString] : array_filter(explode(' ', $ftString)); foreach ($tokens as $t) { $ex = $t[0] === '-'; @@ -646,17 +646,22 @@ abstract class Filter $sub[] = ($ex ? '-' : '+') . $t . '*'; } - $qry = []; - foreach ($fields as $f) - $qry[] = [$f, $sub, 'MATCH']; - - // single cnd? - if (!$qry) + if (!$sub) { - trigger_error('Filter::buildMatchLookup - could build MATCH AGAINST from: '.$string, E_USER_NOTICE); + trigger_error('Filter::buildMatchLookup - could not build MATCH AGAINST from: "'.$ftString.'"', E_USER_NOTICE); $this->error = true; } - else if (count($qry) > 1) + + $qry = []; + foreach ($fields as $f) + { + $qry[] = [$f, trim($string)]; + if ($sub) + $qry[] = [$f, $sub, 'MATCH']; + } + + // single cnd? + if (count($qry) > 1) array_unshift($qry, 'OR'); else $qry = $qry[0]; diff --git a/includes/components/search.class.php b/includes/components/search.class.php index 6af35a9d..bc8c9182 100644 --- a/includes/components/search.class.php +++ b/includes/components/search.class.php @@ -112,7 +112,7 @@ class Search foreach (explode(' ', $this->query) as $raw) { - // ivalid chars for both LIKE and MATCH + // invalid chars for both LIKE and MATCH $clean = str_replace(['\\', '%'], '', $raw); if ($clean === '') @@ -197,16 +197,17 @@ class Search if (Lang::getLocale()->isLogographic() && !Cfg::get('LOGOGRAPHIC_FT_SEARCH')) return $this->createLikeLookup($fields); - if (!$this->fulltext) - return []; - // default to name-field if (!$fields) $fields[] = 'name_loc'.Lang::getLocale()->value; $qry = []; foreach ($fields as $f) - $qry[] = [$f, $this->fulltext, 'MATCH']; + { + $qry[] = [$f, $this->query]; + if ($this->fulltext) + $qry[] = [$f, $this->fulltext, 'MATCH']; + } // single cnd? if (count($qry) > 1) diff --git a/setup/sql/01-db_structure.sql b/setup/sql/01-db_structure.sql index 57a96af9..4196c9da 100644 --- a/setup/sql/01-db_structure.sql +++ b/setup/sql/01-db_structure.sql @@ -578,11 +578,17 @@ CREATE TABLE `aowow_creature` ( KEY `idx_skinloot` (`skinLootId`), KEY `idx_trainer` (`trainerType`), KEY `idx_trainerrequirement` (`trainerRequirement`), - FULLTEXT `idx_name0` (`name_loc0`), - FULLTEXT `idx_name2` (`name_loc2`), - FULLTEXT `idx_name3` (`name_loc3`), - FULLTEXT `idx_name6` (`name_loc6`), - FULLTEXT `idx_name8` (`name_loc8`), + FULLTEXT `idx_ft_name0` (`name_loc0`), + FULLTEXT `idx_ft_name2` (`name_loc2`), + FULLTEXT `idx_ft_name3` (`name_loc3`), + FULLTEXT `idx_ft_name6` (`name_loc6`), + FULLTEXT `idx_ft_name8` (`name_loc8`), + KEY `idx_name0` (`name_loc0`), + KEY `idx_name2` (`name_loc2`), + KEY `idx_name3` (`name_loc3`), + KEY `idx_name4` (`name_loc4`), + KEY `idx_name6` (`name_loc6`), + KEY `idx_name8` (`name_loc8`), KEY `idx_spell1` (`spell1`), KEY `idx_spell2` (`spell2`), KEY `idx_spell3` (`spell3`), @@ -1470,11 +1476,17 @@ CREATE TABLE `aowow_items` ( KEY `idx_trigger4` (`spellTrigger4`), KEY `idx_trigger5` (`spellTrigger5`), KEY `idx_reqskill` (`requiredSkill`), - FULLTEXT `idx_name0` (`name_loc0`), - FULLTEXT `idx_name2` (`name_loc2`), - FULLTEXT `idx_name3` (`name_loc3`), - FULLTEXT `idx_name6` (`name_loc6`), - FULLTEXT `idx_name8` (`name_loc8`), + FULLTEXT `idx_ft_name0` (`name_loc0`), + FULLTEXT `idx_ft_name2` (`name_loc2`), + FULLTEXT `idx_ft_name3` (`name_loc3`), + FULLTEXT `idx_ft_name6` (`name_loc6`), + FULLTEXT `idx_ft_name8` (`name_loc8`), + KEY `idx_name0` (`name_loc0`), + KEY `idx_name2` (`name_loc2`), + KEY `idx_name3` (`name_loc3`), + KEY `idx_name4` (`name_loc4`), + KEY `idx_name6` (`name_loc6`), + KEY `idx_name8` (`name_loc8`), KEY `idx_itemset` (`itemset`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -1664,11 +1676,17 @@ CREATE TABLE `aowow_objects` ( KEY `idx_onsuccessspell` (`onSuccessSpell`), KEY `idx_auraspell` (`auraSpell`), KEY `idx_triggeredspell` (`triggeredSpell`), - FULLTEXT `idx_name0` (`name_loc0`), - FULLTEXT `idx_name2` (`name_loc2`), - FULLTEXT `idx_name3` (`name_loc3`), - FULLTEXT `idx_name6` (`name_loc6`), - FULLTEXT `idx_name8` (`name_loc8`) + FULLTEXT `idx_ft_name0` (`name_loc0`), + FULLTEXT `idx_ft_name2` (`name_loc2`), + FULLTEXT `idx_ft_name3` (`name_loc3`), + FULLTEXT `idx_ft_name6` (`name_loc6`), + FULLTEXT `idx_ft_name8` (`name_loc8`), + KEY `idx_name0` (`name_loc0`), + KEY `idx_name2` (`name_loc2`), + KEY `idx_name3` (`name_loc3`), + KEY `idx_name4` (`name_loc4`), + KEY `idx_name6` (`name_loc6`), + KEY `idx_name8` (`name_loc8`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -2267,11 +2285,17 @@ CREATE TABLE `aowow_quests` ( `objectiveText4_loc8` text DEFAULT NULL, PRIMARY KEY (`id`), KEY `nextQuestIdChain` (`nextQuestIdChain`), - FULLTEXT `idx_name0` (`name_loc0`), - FULLTEXT `idx_name2` (`name_loc2`), - FULLTEXT `idx_name3` (`name_loc3`), - FULLTEXT `idx_name6` (`name_loc6`), - FULLTEXT `idx_name8` (`name_loc8`), + FULLTEXT `idx_ft_name0` (`name_loc0`), + FULLTEXT `idx_ft_name2` (`name_loc2`), + FULLTEXT `idx_ft_name3` (`name_loc3`), + FULLTEXT `idx_ft_name6` (`name_loc6`), + FULLTEXT `idx_ft_name8` (`name_loc8`), + KEY `idx_name0` (`name_loc0`), + KEY `idx_name2` (`name_loc2`), + KEY `idx_name3` (`name_loc3`), + KEY `idx_name4` (`name_loc4`), + KEY `idx_name6` (`name_loc6`), + KEY `idx_name8` (`name_loc8`), KEY `idx_sourcespell` (`sourceSpellId`), KEY `idx_rewardspell` (`rewardSpell`), KEY `idx_rewardcastspell` (`rewardSpellCast`), @@ -2875,11 +2899,17 @@ CREATE TABLE `aowow_spell` ( KEY `effect3AuraId` (`effect3AuraId`), KEY `idx_skill1` (`skillLine1`), KEY `idx_skill2` (`skillLine2OrMask`), - FULLTEXT `idx_name0` (`name_loc0`), - FULLTEXT `idx_name2` (`name_loc2`), - FULLTEXT `idx_name3` (`name_loc3`), - FULLTEXT `idx_name6` (`name_loc6`), - FULLTEXT `idx_name8` (`name_loc8`), + FULLTEXT `idx_ft_name0` (`name_loc0`), + FULLTEXT `idx_ft_name2` (`name_loc2`), + FULLTEXT `idx_ft_name3` (`name_loc3`), + FULLTEXT `idx_ft_name6` (`name_loc6`), + FULLTEXT `idx_ft_name8` (`name_loc8`), + KEY `idx_name0` (`name_loc0`), + KEY `idx_name2` (`name_loc2`), + KEY `idx_name3` (`name_loc3`), + KEY `idx_name4` (`name_loc4`), + KEY `idx_name6` (`name_loc6`), + KEY `idx_name8` (`name_loc8`), KEY `idx_spellfamily` (`spellFamilyId`), KEY `idx_miscvalue1` (`effect1MiscValue`), KEY `idx_miscvalue2` (`effect2MiscValue`), diff --git a/setup/sql/updates/1770626911_01.sql b/setup/sql/updates/1770626911_01.sql new file mode 100644 index 00000000..a71c1fa1 --- /dev/null +++ b/setup/sql/updates/1770626911_01.sql @@ -0,0 +1,91 @@ +SET SESSION innodb_ft_enable_stopword = OFF; + +ALTER TABLE aowow_creature + DROP INDEX idx_name0, + DROP INDEX idx_name2, + DROP INDEX idx_name3, + DROP INDEX idx_name6, + DROP INDEX idx_name8, + ADD INDEX idx_name0 (`name_loc0`), + ADD INDEX idx_name2 (`name_loc2`), + ADD INDEX idx_name3 (`name_loc3`), + ADD INDEX idx_name4 (`name_loc4`), + ADD INDEX idx_name6 (`name_loc6`), + ADD INDEX idx_name8 (`name_loc8`), + ADD FULLTEXT idx_ft_name0 (`name_loc0`), + ADD FULLTEXT idx_ft_name2 (`name_loc2`), + ADD FULLTEXT idx_ft_name3 (`name_loc3`), + ADD FULLTEXT idx_ft_name6 (`name_loc6`), + ADD FULLTEXT idx_ft_name8 (`name_loc8`); + +ALTER TABLE aowow_items + DROP INDEX idx_name0, + DROP INDEX idx_name2, + DROP INDEX idx_name3, + DROP INDEX idx_name6, + DROP INDEX idx_name8, + ADD INDEX idx_name0 (`name_loc0`), + ADD INDEX idx_name2 (`name_loc2`), + ADD INDEX idx_name3 (`name_loc3`), + ADD INDEX idx_name4 (`name_loc4`), + ADD INDEX idx_name6 (`name_loc6`), + ADD INDEX idx_name8 (`name_loc8`), + ADD FULLTEXT idx_ft_name0 (`name_loc0`), + ADD FULLTEXT idx_ft_name2 (`name_loc2`), + ADD FULLTEXT idx_ft_name3 (`name_loc3`), + ADD FULLTEXT idx_ft_name6 (`name_loc6`), + ADD FULLTEXT idx_ft_name8 (`name_loc8`); + +ALTER TABLE aowow_objects + DROP INDEX idx_name0, + DROP INDEX idx_name2, + DROP INDEX idx_name3, + DROP INDEX idx_name6, + DROP INDEX idx_name8, + ADD INDEX idx_name0 (`name_loc0`), + ADD INDEX idx_name2 (`name_loc2`), + ADD INDEX idx_name3 (`name_loc3`), + ADD INDEX idx_name4 (`name_loc4`), + ADD INDEX idx_name6 (`name_loc6`), + ADD INDEX idx_name8 (`name_loc8`), + ADD FULLTEXT idx_ft_name0 (`name_loc0`), + ADD FULLTEXT idx_ft_name2 (`name_loc2`), + ADD FULLTEXT idx_ft_name3 (`name_loc3`), + ADD FULLTEXT idx_ft_name6 (`name_loc6`), + ADD FULLTEXT idx_ft_name8 (`name_loc8`); + +ALTER TABLE aowow_quests + DROP INDEX idx_name0, + DROP INDEX idx_name2, + DROP INDEX idx_name3, + DROP INDEX idx_name6, + DROP INDEX idx_name8, + ADD INDEX idx_name0 (`name_loc0`), + ADD INDEX idx_name2 (`name_loc2`), + ADD INDEX idx_name3 (`name_loc3`), + ADD INDEX idx_name4 (`name_loc4`), + ADD INDEX idx_name6 (`name_loc6`), + ADD INDEX idx_name8 (`name_loc8`), + ADD FULLTEXT idx_ft_name0 (`name_loc0`), + ADD FULLTEXT idx_ft_name2 (`name_loc2`), + ADD FULLTEXT idx_ft_name3 (`name_loc3`), + ADD FULLTEXT idx_ft_name6 (`name_loc6`), + ADD FULLTEXT idx_ft_name8 (`name_loc8`); + +ALTER TABLE aowow_spell + DROP INDEX idx_name0, + DROP INDEX idx_name2, + DROP INDEX idx_name3, + DROP INDEX idx_name6, + DROP INDEX idx_name8, + ADD INDEX idx_name0 (`name_loc0`), + ADD INDEX idx_name2 (`name_loc2`), + ADD INDEX idx_name3 (`name_loc3`), + ADD INDEX idx_name4 (`name_loc4`), + ADD INDEX idx_name6 (`name_loc6`), + ADD INDEX idx_name8 (`name_loc8`), + ADD FULLTEXT idx_ft_name0 (`name_loc0`), + ADD FULLTEXT idx_ft_name2 (`name_loc2`), + ADD FULLTEXT idx_ft_name3 (`name_loc3`), + ADD FULLTEXT idx_ft_name6 (`name_loc6`), + ADD FULLTEXT idx_ft_name8 (`name_loc8`);