从字符串中返回前 100 个单词

Use*_*425 5 postgresql full-text-search

不确定这是否可行,但我想知道是否有任何方法可以使用 PostgreSQL 从包含不同长度的字符串的数据库列中返回前 100 个最常出现的单词?

该表包含约 250k 行,每行包含message许多其他元数据。那么,有没有办法筛选每一行中的每个单词,获取它出现的总次数并将其与同一列中所有其他单词的计数进行比较以返回前 100 个?

如果更容易,可以删除元数据以仅保留包含推文的列。

理想情况下,我希望能够执行该网站所做的工作以提供相同的输出,但只有更多的记录。

Erw*_*ter 6

假设多个“单词”由空格字符分隔。

不清楚您是要比较整个表的总计数还是每行的计数。对于整个表

SELECT word, count(*) AS ct
FROM   tbl, unnest(string_to_array(message, ' ')) word  -- implicit LATERAL join
GROUP  BY 1
ORDER  BY 2 DESC
LIMIT  100;  -- top 100
Run Code Online (Sandbox Code Playgroud)

或者,使用SELECT列表中的 set-returning 函数更快但不太干净:

SELECT unnest(string_to_array(message, ' ')) AS word, count(*) AS ct
FROM   tbl
GROUP  BY 1
ORDER  BY 2 DESC
LIMIT  100;
Run Code Online (Sandbox Code Playgroud)

对于自然语言文本,您可以做更多的事情:删除标点符号、比较词干等。全文搜索提供了各种工具。在调试功能ts_stat(),似乎为这个特别方便。对于英文文本:

SELECT word, ndoc, nentry
FROM   ts_stat($$SELECT to_tsvector('english', message) FROM tbl$$) 
ORDER  BY nentry DESC
LIMIT  100;
Run Code Online (Sandbox Code Playgroud)

ndoc.. 行数
nentry.. 出现次数(在单个文本中有多个实例时可以更大。

该查询返回整个表中列中最常见的单词 - 就像第一个查询一样,但现在标点符号和停用词被修剪,单词被缩减为它们的英文词干。

要查找最多行中包含的单词,请改用:

ORDER  BY ndoc DESC
Run Code Online (Sandbox Code Playgroud)

人们可能会认为它应该是可以使用的功能GIN索引to_tsvector('english', message),使这个速度非常快。但是我没有在快速测试中找到方法。