我想知道是否可以创建一个 Postgres 函数来扫描一些表行并创建一个包含WORD
和AMOUNT
(频率)的表?我的目标是使用这个表来创建一个词云。
问问题
2380 次
2 回答
5
有一种简单的方法,但它可能会很慢(取决于您的桌子大小)。您可以将文本拆分为数组:
SELECT string_to_array(lower(words), ' ') FROM table;
使用这些数组,您可以使用unnest
它们来聚合它们:
WITH words AS (
SELECT unnest(string_to_array(lower(words), ' ')) AS word
FROM table
)
SELECT word, count(*) FROM words
GROUP BY word;
这是一种简单的方法,但存在一些问题,例如,它只用空格而不是标点符号来分割单词。
其他可能更好的选择是使用PostgreSQL 全文搜索。
于 2013-02-19T12:57:34.433 回答
4
聚会迟到了,但我也需要这个,并想使用全文搜索。
可以方便地删除 html 标签。
所以基本上你将文本转换为 atsvector
然后使用ts_stat
:
select word, nentry
from ts_stat($q$
select to_tsvector('simple', '<div id="main">a b c <b>b c</b></div>')
$q$)
order by nentry desc
结果:
|word|nentry|
|----|------|
|c |2 |
|b |2 |
|a |1 |
但这不能很好地扩展,所以这就是我的想法:
设置:
-- table with a gist index on the tsvector column
create table wordcloud_data (
html text not null,
tsv tsvector not null
);
create index on wordcloud_data using gist (tsv);
-- trigger to update the tsvector column
create trigger wordcloud_data_tsvupdate
before insert or update on wordcloud_data
for each row execute function tsvector_update_trigger(tsv, 'pg_catalog.simple', html);
-- a view for the wordcloud
create view wordcloud as select word, nentry from ts_stat('select tsv from wordcloud_data') order by nentry desc;
用法:
-- insert some data
insert into wordcloud_data (html) values
('<div id="id1">aaa</div> <b>bbb</b> <i attribute="ignored">ccc</i>'),
('<div class="class1"><span>bbb</span> <strong>ccc</strong> <pre>ddd</pre></div>');
之后,您的wordcloud
视图应如下所示:
|word|nentry|
|----|------|
|ccc |2 |
|bbb |2 |
|ddd |1 |
|aaa |1 |
额外功能:
替换simple
为例如english
,postgres 将删除停用词并为您进行词干提取。
于 2020-06-17T21:07:52.733 回答