我最近一直在一些数据库搜索功能,并希望得到(在数据库例如文本字段)像一张原稿的平均单词的一些信息。我已经(在DB以外所选择的语言而无需处理)迄今发现的唯一事情是:

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

这似乎是工作,但*你有其他的建议?我目前使用MySQL 4(希望尽快移动到第5版为这个应用程序),但也很感兴趣,一般的解决方案。

谢谢!

*我可以想像,这是一个非常粗略的方式来确定这个,因为它并不在内容占HTML之类为好。这对于这个特定的项目确定,但再有没有更好的办法?

更新::要界定什么我所说的“更好”:要么更准确,更有效地执行,或者是更“正确”(易维护,好做法,等等)。因为我有可用的内容,上面的查询足够快而且准确这个项目,但我可能需要在未来类似的东西(所以我问)。

有帮助吗?

解决方案

的MySQL的文本处理能力不是你想要的东西不够好。存储函数是一种选择,但可能是缓慢的。到MySQL内处理数据最好的办法是添加定义的用户功能。如果你要建立一个更新的MySQL版本,无论如何,你还可以添加的机函数

在“正确”的方式是处理DB外的数据,因为DB是用于存储,不处理,以及任何重处理可能使太多的DBMS的负载。此外,在计算字数的MySQL之外可以更容易地改变一个单词的计算的定义。如何存储在所述DB中的字计数和更新它,当一个文件被改变?

实施例存储的函数:

DELIMITER $$
CREATE FUNCTION wordcount(str LONGTEXT)
       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);
    SET idx = 1;
    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 ;

其他提示

这是一个相当快一点,但只要稍微不太准确。我发现4%的光上的计数,这是“估计”的场景确定。

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

可以使用从 https://github.com/spachev/mysql_udf_bundle word_count() UDF。我移植从接受答案的逻辑与我的代码只支持LATIN1字符集的差异。逻辑将需要修改,以支持其它字符集。此外,这两种实施方式始终考虑非字母数字字符是定界符,这可能并不总是可取的。 - 例如“老师的书”被认为是三个词由两个实现

在UDF版本是,当然,显著更快。对于一个快速测试,我都尝试从项目加滕伯格由9751个记录总计约3 GB的数据集。该UDF做了所有的人在18秒内,而存储功能了63秒处理仅30记录(这确实UDF 0.05秒)。因此,UDF是在这种情况下更快的大致000倍。

UDF将击败在速度的任何其它方法,不涉及修改的MySQL源代码。这是因为它具有访问字符串字节内存和他们无需到处移动可以在字节直接操作。它也编译成机器代码,直接运行在CPU上。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top