Можно ли использовать soundex для части столбца в MySQL?
Можно ли использовать soundex для сравнения части столбца с поисковым термином? Например, если пользователь ищет "пятьдесят три" - он найдет "Nirve Sports Fifty-Three Cruiser in Gold Metallic". Я попытался объединить soundex с функцией locate, но получил ошибку. Вот мой PHP-код:
$soundex = soundex($keyword);
$soundexPrefix = substr($soundex, 0, 2);
$sql = "SELECT name ".
"FROM products WHERE SOUNDEX(LOCATE('$keyword', name)) LIKE '%$soundexPrefix%'";
2 ответа
Вам нужно разбить каждое слово и сделать SOUNDEX
Сравнение, о котором я собираюсь рассказать вам в этой функции.
Используя функцию
Пример использования: SELECT p.name FROM products p WHERE soundex_match('fiftythree', p.name, ' ')
Требуется 3 аргумента:
- игла: слово, которое вы ищете
- стог сена: строка слов, среди которых вы ищете
- splitChar: символ пробела, который разделит строку на отдельные слова. Обычно это пробел ('')
Если какое-либо слово в стоге сена звучит похоже на иглу, в противном случае функция вернет 1 и 0.
Создание функции в вашей базе данных
Поэтому зайдите в свою базу данных (phpMyAdmin или командную строку) и выполните это, вам нужно сделать это только один раз):
drop function if exists soundex_match;
delimiter $$
create function soundex_match (needle varchar(128), haystack text, splitChar varchar(1)) returns tinyint
deterministic
begin
declare spacePos int;
declare searchLen int default length(haystack);
declare curWord varchar(128) default '';
declare tempStr text default haystack;
declare tmp text default '';
declare soundx1 varchar(64) default soundex(needle);
declare soundx2 varchar(64) default '';
set spacePos = locate(splitChar, tempStr);
while searchLen > 0 do
if spacePos = 0 then
set tmp = tempStr;
select soundex(tmp) into soundx2;
if soundx1 = soundx2 then
return 1;
else
return 0;
end if;
end if;
if spacePos != 0 then
set tmp = substr(tempStr, 1, spacePos-1);
set soundx2 = soundex(tmp);
if soundx1 = soundx2 then
return 1;
end if;
set tempStr = substr(tempStr, spacePos+1);
set searchLen = length(tempStr);
end if;
set spacePos = locate(splitChar, tempStr);
end while;
return 0;
end
$$
delimiter ;
http://www.imranulhoque.com/mysql/mysql-function-soundex-match-multi-word-string/
Возвращаясь к этому вопросу; Я обновил решение @msigman для размещения строк разной длины (т. е. «Джеймс» похож на «Джеймстаун»)...
DROP FUNCTION IF EXISTS senf_soundex;
DELIMITER $$
CREATE FUNCTION senf_soundex (_needle VARCHAR(128), _haystack TEXT, _delimiter VARCHAR(1))
RETURNS TINYINT
DETERMINISTIC
BEGIN
DECLARE int_index INT;
DECLARE int_length INT DEFAULT LENGTH(_haystack);
DECLARE int_result TINYINT DEFAULT 0;
DECLARE str_remnant TEXT DEFAULT _haystack;
DECLARE snd_needle VARCHAR(64) DEFAULT TRIM(TRAILING '0' FROM LEFT(SOUNDEX(_needle), 4));
SET int_index = LOCATE(_delimiter, str_remnant);
WHILE int_length > 0 DO
IF int_index = 0 THEN
SET int_result = IF(snd_needle = LEFT(SOUNDEX(str_remnant), LEAST(4, LENGTH(snd_needle))),1,0);
RETURN int_result;
ELSE
IF snd_needle = LEFT(SOUNDEX(SUBSTR(str_remnant, 1, int_index-1)), LEAST(4, LENGTH(snd_needle))) THEN
RETURN 1;
END IF;
SET str_remnant = SUBSTR(str_remnant, int_index+1);
SET int_length = LENGTH(str_remnant);
END IF;
SET int_index = LOCATE(_delimiter, str_remnant);
END WHILE;
RETURN 0;
END
$$ DELIMITER ;