Подтвердить что ты не робот

Использование SQL для определения статистики слов в текстовом поле

Недавно я работал над некоторыми функциями поиска базы данных и хотел получить некоторую информацию, например, средние слова на один документ (например, текстовое поле в базе данных). Единственное, что я нашел до сих пор (без обработки на языке выбора вне БД):

SELECT AVG(LENGTH(content) - LENGTH(REPLACE(content, ' ', '')) + 1)
FROM documents

Это похоже на работу *, но есть ли у вас другие предложения? В настоящее время я использую MySQL 4 (надеюсь, скоро перейдем к версии 5 для этого приложения), но я также заинтересован в общих решениях.

Спасибо!

* Я могу представить, что это довольно грубый способ определить это, поскольку он не учитывает HTML в контенте и тому подобное. Это нормально для этого конкретного проекта, но опять же есть пути лучше?

Обновление:. Чтобы определить, что я имею в виду под "лучше": более точный, более эффективный или более "правильный" (простой в обслуживании, хорошая практика и т.д.). Для контента, который у меня есть, запрос выше достаточно быстр и является точным для этого проекта, но мне может понадобиться нечто подобное в будущем (поэтому я спросил).

4b9b3361

Ответ 1

Возможности обработки текста MySQL недостаточно хороши для того, что вы хотите. Сохраненная функция является опцией, но, вероятно, будет медленной. Лучше всего обрабатывать данные в MySQL, чтобы добавить функцию пользовательскую функцию. Если вы все равно собираетесь строить новую версию MySQL, вы также можете добавить родную функцию.

"Правильный" способ заключается в обработке данных вне БД, поскольку базы данных хранятся, а не обрабатываются, и любая тяжелая обработка может накладывать слишком большую нагрузку на СУБД. Кроме того, вычисление подсчета слов вне MySQL упрощает изменение определения того, что считается словом. Как сохранить количество слов в БД и обновить его при изменении документа?

Пример сохраненной функции:

DELIMITER $$
CREATE FUNCTION wordcount(str TEXT)
       RETURNS INT
       DETERMINISTIC
       SQL SECURITY INVOKER
       NO SQL
  BEGIN
    DECLARE wordCnt, idx, maxIdx INT DEFAULT 0;
    DECLARE currChar, prevChar BOOL DEFAULT 0;
    SET maxIdx=char_length(str);
    WHILE idx < maxIdx DO
        SET currChar=SUBSTRING(str, idx, 1) RLIKE '[[:alnum:]]';
        IF NOT prevChar AND currChar THEN
            SET wordCnt=wordCnt+1;
        END IF;
        SET prevChar=currChar;
        SET idx=idx+1;
    END WHILE;
    RETURN wordCnt;
  END
$$
DELIMITER ;

Ответ 2

Это довольно немного быстрее, хотя и немного менее точно. Я обнаружил, что он подсчитал 4% на счетчике, что подходит для сценариев "оценки".

SELECT
    ROUND (   
        (
            CHAR_LENGTH(content) - CHAR_LENGTH(REPLACE (content, " ", "")) 
        ) 
        / CHAR_LENGTH(" ")        
    ) AS count    
FROM documents