【问题标题】:Postgres Find and Return Keywords From List Within SelectPostgres 从 Select 中的列表中查找并返回关键字
【发布时间】:2015-12-08 17:38:31
【问题描述】:

我有一个简单的 postgres 表,其中包含一个 cmets(文本)列。 在一个视图中,我需要在 cmets 字段中搜索单词列表,然后返回一个以逗号分隔的单词列表,其中包含一列(以及一堆普通列)。

定义的关键字列表包含大约 20 个单词。 IE。苹果、香蕉、梨、桃、李子。

理想的结果是这样的:

id | comments                    | keywords
-----------------------------------------------------
1  | I like bananas!             | bananas
2  | I like apples.              | apples
3  | I don't like fruit          | 
4  | I like apples and bananas!  | apples,bananas

我在想我需要做一个子查询和array_agg?或者可能是“在哪里”。但我不知道如何将它固定在一起。

非常感谢, 史蒂夫

【问题讨论】:

  • 你怎么知道关键字是什么,什么不是?
  • @a_horse_with_no_name 是什么意思?我已经定义了要查找的关键字列表 - 我认为其中大约 20 个。

标签: postgresql search full-text-search keyword-search array-agg


【解决方案1】:

您可以使用全文搜索工具来获得结果:

  1. 使用您的单词列表设置新的ispell dictionary
  2. 根据您的字典创建full-text search configuration。不要忘记从配置中删除所有其他字典,因为在您的情况下,所有其他单词实际上都是停用词。

之后当你执行时

select plainto_tsquery('<your config name>', 'I like apples and bananas!')

如果您正确设置字典,您将只获得关键字:'apples' &amp; 'bananas' 甚至是'apple' &amp; 'banana'

默认情况下,英文配置使用减少词尾的雪球词典,所以如果你运行

select plainto_tsquery('english', 'I like apples and bananas!')

你会得到

'like' & 'appl' & 'banana'

这不完全适合您的情况。

【讨论】:

  • 感谢@TnT - 这非常有帮助。我在这方面取得了不错的进展——但我的单词和其他东西,如数字和未知短语(即 100、晚上 10 点等)都得到了回复。有没有办法忽略除我的单词列表之外的所有内容?
  • 到目前为止我的配置:CREATE TEXT SEARCH CONFIGURATION public.nrw (COPY = pg_catalog.english);创建文本搜索字典 nrw_dict_ispell(模板 = ispell,DictFile = nrw_dict,AffFile = nrw_dict);更改文本搜索配置 nrw 删除电子邮件、url、url_path、sfloat、float、int 的映射; ALTER TEXT SEARCH CONFIGURATION nrw ALTER MAPPING FOR asciiword, asciihword, hword_asciipart, word, hword, hword_part WITH nrw_dict_ispell;
  • 通过执行 regex_replace 解决了数字问题。一旦数字被删除,关键词就完美地返回了!
【解决方案2】:

另一种更简单的方法(但速度较慢):

创建字典表:

create table keywords (nm text);

insert into keywords (nm)
values ('apples'), ('bananas');

对您的文本执行以下脚本以提取关键字

select string_agg(regexp_replace(foo, '[^a-zA-Z\-]*', '', 'ig'), ',') s
  from regexp_split_to_table('I like apples and bananas!', E'\\s+') foo 
 where regexp_replace(foo, '[^a-zA-Z\-]*', '', 'ig') in (select nm from keywords)

这个方案在语义上比较差,所以banana和bananas会是不同的关键词。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-08
    • 1970-01-01
    • 2016-06-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多