MySQL - сравнить два поля и вернуть совпадение в процентах

В настоящее время у нас есть веб-сайт, который хранит текст, добавленный пользователем, в виде среднего текста.

В настоящее время наша система проверяет текст на совпадение и возвращает истину (да, совпадение), когда оно составляет 1:1 (100% то же самое — один пробел, и он будет принят как новый текст).

Мы пытаемся сделать систему умнее. Должна быть возможность сказать нам в процентах, насколько содержимое одинаково (в процентах). К сожалению, у нас нет хорошего прогресса. Почти все алгоритмы, которые мы могли придумать, работали неправильно или были ОЧЕНЬ медленными и тяжелыми.

Мы надеемся, что кто-то сможет дать нам толчок.

Примечание. Мы пытались выполнить сравнение байтов, но ничего не получилось.

РЕДАКТИРОВАТЬ: мы не ограничиваемся только MySQL. Мы искали сервер apache solr. Если у него есть преимущества, пожалуйста, помогите в этом направлении или сделайте что-нибудь лучше, если есть.


person kanevbgbe    schedule 30.11.2012    source источник
comment
Вы видели полнотекстовый поиск?   -  person Kermit    schedule 30.11.2012
comment
Да, но не устраивает. У вас есть идеи для сопоставления содержимого в процентах?   -  person kanevbgbe    schedule 01.12.2012


Ответы (1)


Вам нужно вычислить расстояние Левенштейна.

http://en.wikipedia.org/wiki/Levenshtein_distance

Пример на SO: MySQL Левенштейн

DELIMITER $$

CREATE FUNCTION LEVENSHTEIN( s1 CHAR(255), s2 CHAR(255)) 
RETURNS int(3) 
DETERMINISTIC
BEGIN
    DECLARE s1_len, s2_len, i, j, c, c_temp, cost INT;
    DECLARE s1_char CHAR(255);
    DECLARE cv0, cv1 CHAR(255);

    SET s1_len = LENGTH(s1);
    SET s2_len = LENGTH(s2);
    SET cv1 = 0x00;
    SET j = 1;
    SET i = 1;
    SET c = 0;

    IF s1 = s2 THEN
        RETURN 0;
    ELSE IF s1_len = 0 THEN
        RETURN s2_len;
    ELSE IF s2_len = 0 THEN
        RETURN s1_len;
    ELSE
        WHILE j <= s2_len DO 
          SET c = c + 1; 
          IF s1_char = SUBSTRING(s2, j, 1) THEN  
            SET cost = 0; ELSE SET cost = 1; 
          END IF; 
          SET c_temp = CONV(HEX(SUBSTRING(cv1, j, 1)), 16, 10) + cost; 
                SET c_temp = CONV(HEX(SUBSTRING(cv1, j+1, 1)), 16, 10) + 1;
                IF c > c_temp THEN
                    SET c = c_temp;
                END IF;
                SET cv0 = CONCAT(cv0, UNHEX(HEX(c))), j = j + 1;
            END WHILE;
            SET cv1 = cv0, i = i + 1;
        END WHILE;
    END IF;
    RETURN c;
END$$

DELIMITER ;
person kcsoft    schedule 30.11.2012
comment
Привет. Можете ли вы дать мне дополнительную помощь, так как mysql возвращает ошибку: правильный синтаксис для использования рядом с 'WHILE; КОНЕЦ ЕСЛИ; ВОЗВРАТ с; КОНЕЦ» в строке 36 - person kanevbgbe; 30.11.2012
comment
извините, не мой код. Вы можете поискать в Google другие реализации mysql. Мой ответ - просто направить вас на правильный путь, а не дать полное решение. - person kcsoft; 30.11.2012
comment
Я исправил это, и это очень-очень медленно для той цели, которая нам нужна. Результат: показаны строки 10–9 (всего 10, запрос занял 232,2726 с). - person kanevbgbe; 01.12.2012