Я поддерживаю базу данных музыки в mySQL, как мне возвращать результаты, хранящиеся под eg 'Tiësto', когда люди ищут «Tiesto»?
Все данные хранятся под индексом полного текста, если это имеет значение.
Я уже использую комбинацию Levenshtein в PHP и REGEXP в SQL – не пытаюсь решить эту проблему, а просто для большей доступности для поиска в целом.
PHP:
function Levenshtein($word) { $words = array(); for ($i = 0; $i < strlen($word); $i++) { $words[] = substr($word, 0, $i) . '_' . substr($word, $i); $words[] = substr($word, 0, $i) . substr($word, $i + 1); $words[] = substr($word, 0, $i) . '_' . substr($word, $i + 1); } $words[] = $word . '_'; return $words; } $fuzzyartist = Levenshtein($_POST['searchartist']); $searchimplode = "'".implode("', '", $fuzzyartist)."'";
MySql:
SELECT * FROM new_track_database WHERE artist REGEXP concat_ws('|', $searchimplode);
Чтобы добавить, я часто выполняю преобразования набора символов и строчную санитарию в PHP, но они всегда были ДРУГОЙ способ – стандартизация не латинских символов. Я не могу понять, как выполнить oppsite-процесс, но только в определенных обстоятельствах, основанных на данных, которые я сохранил.
Возможным решением будет создание другого столбца в базе данных рядом с «художником», например «artist_normalized». Здесь, заполняя таблицу, вы можете вставить «нормализованную» версию строки. Затем поиск может быть выполнен против столбца artist_normalized.
Код проверки:
<?php $transliterator = Transliterator::createFromRules(':: NFD; :: [:Nonspacing Mark:] Remove; :: NFC;', Transliterator::FORWARD); $test = ['abcd', 'èe', '€', 'àòùìéëü', 'àòùìéëü', 'tiësto']; foreach($test as $e) { $normalized = $transliterator->transliterate($e); echo $e. ' --> '.$normalized."\n"; } ?>
Результат:
abcd --> abcd èe --> ee € --> € àòùìéëü --> aouieeu àòùìéëü --> aouieeu tiësto --> tiesto
Магия выполняется классом Transliterator. Указанное правило выполняет три действия: разлагает строку, удаляет диакритические символы, а затем переупорядочивает строку, канонизированную. Транслитератор в PHP построен поверх ICU, поэтому, делая это, вы полагаетесь на таблицы библиотеки ICU, которые являются полными и надежными.
Примечание. Для этого решения требуется PHP 5.4 или выше с расширением intl .