Как я могу токенизировать строку в MySQL?

Мой проект импортирует большую коллекцию (+500 тыс. строк данных) из плоских файлов Excel, созданных вручную группой людей. Теперь проблема в том, что это все нужно нормализовать, для поиска клиентов. Например, поле компании будет иметь несколько вариантов написания компании и включать в себя филиалы, такие как «IBM», а затем «IBM Inc.». и "IBM Japan" и т. д. Кроме того, у меня есть названия продуктов, которые являются буквенно-цифровыми, например "A46-Rhizonme Pentahol", с которыми SOUNDEX не может справиться самостоятельно.

Я могу решить эту проблему в долгосрочной перспективе, если все вводимые данные будут осуществляться через веб-форму с автоматической подсказкой AJAX. Однако до тех пор мне все еще нужно иметь дело с массивным сбором существующих данных. Это подводит меня к тому, что я считаю хорошим процессом, основываясь на том, что я прочитал здесь:

http://msdn.microsoft.com/en-us/magazine/cc163731.aspx

Шаги для создания пользовательского поиска нечеткой логики и группировки нечеткой логики

  1. Пункт списка
  2. разбить строки на ключевые слова
  3. вычислить ключевое слово TF-IDF (общая частота - обратная частота документа)
  4. рассчитать расстояние Левенштейна между ключевыми словами
  5. рассчитать Soundex по доступным альфа-строкам
  6. определить контекст ключевых слов
  7. размещать ключевые слова в зависимости от контекста в отдельные таблицы БД, такие как «Компании», «Продукты», «Ингредиенты»

Я гуглил, искал StackOverflow, читал обсуждения MySQL.com и т. Д. Об этой проблеме, чтобы попытаться найти готовое решение. Любые идеи?


person Apollo Clark    schedule 15.12.2011    source источник


Ответы (2)


Итак, я сдался и просто сделал функцию токенизации строк для mysql. Вот код:

CREATE DEFINER = `root`@`localhost` FUNCTION `NewProc`(in_string VARCHAR(255), delims VARCHAR(255), str_replace VARCHAR(255))
 RETURNS varchar(255)
    DETERMINISTIC
BEGIN
    DECLARE str_len, delim_len, a, b, is_delim INT;
    DECLARE z, y VARBINARY(1);
    DECLARE str_out VARBINARY(256);
    SET str_len = CHAR_LENGTH(in_string), delim_len = CHAR_LENGTH(delims),a = 1, b = 1, is_delim = 0, str_out = '';

    -- get each CHARACTER
    WHILE a <= str_len DO
        SET z = SUBSTRING(in_string, a, 1);
        -- loop through the deliminators
        WHILE b <= delim_len AND is_delim < 1 DO
            SET y = SUBSTRING(delims, b, 1);
            -- search for each deliminator
            IF z = y THEN
                SET is_delim = 1;
            END IF;
            SET b = b + 1;
        END WHILE;

        IF is_delim = 1 THEN
            SET str_out = CONCAT(str_out, str_replace);
        ELSE
            SET str_out = CONCAT(str_out, z);
        END IF;

        SET b = 0;
        SET is_delim = 0;
        SET a = a + 1;
    END WHILE;
    RETURN str_out;
END;

Это называется так:

strtok("this.is.my.input.string",".,:;"," | ")

и вернется

"это | это | мой | ввод | строка"

Я надеюсь, что кто-то еще найдет это полезным. Ваше здоровье!

person Apollo Clark    schedule 16.12.2011
comment
Мне это нравится. Единственный способ токенизировать строки в MySQL — это использовать хранимую функцию, подобную вашей. - person Ben English; 17.12.2011
comment
Да, это немного раздражает, хотя MySQL забавно поддерживает REGEX. Я PHP-разработчик, но я больше увлекаюсь MySQL и пытаюсь перенести больше логики в БД для оптимизации. - person Apollo Clark; 20.12.2011
comment
Я думаю, что в случае манипуляций со строками вам лучше делать это в коде вашего приложения. Конечно, бывают ситуации, когда с точки зрения производительности вам придется использовать MySQL, но для этой задачи РСУБД не очень хорошо подходит. Я уверен, что вы видели REGEXP в MySQL и у вас пускались слюни, только чтобы понять, что это не швейцарский армейский нож, как во многих других языках. - person Ben English; 21.12.2011
comment
Интересно... могу ли я спросить, проводили ли вы какие-либо временные сравнения между токенизацией с использованием PHP и использованием вашей функции MySQL? - person mike rodent; 15.06.2013
comment
Майк: Нет, так как производительность будет зависеть от вариантов использования. Если вы хотите токенизировать только пару строк, сделайте это в PH, запросив строки, токенизируйте в PHP и либо выведите в HTML / INSERT / UPDATE и т. д. Однако если вы выполняете умеренно сложный поиск или фильтрацию в MySQL, используя эту функцию токенизации, является лучшим способом вместо того, чтобы извлекать каждую строку для ее обработки в PHP. onextrapixel.com /23/06/2010/ - person Apollo Clark; 17.06.2013

Вы должны проверить Google Refine.

Google Refine — это мощный инструмент для работы с беспорядочными данными, их очистки, преобразования из одного формата в другой, расширения с помощью веб-сервисов и связывания с базами данных, такими как Freebase.

person Chewie    schedule 15.12.2011
comment
Отличный ресурс, спасибо! Мне нужно посмотреть, насколько хорошо он интегрируется, так как это очень ручное решение. Мне любопытно посмотреть, можно ли автоматизировать этот процесс. - person Apollo Clark; 16.12.2011