Postgres匹配正则表达式数组

时间:2016-10-12 15:31:54

标签: sql postgresql

我的客户希望有可能将一组数据与正则表达式数组匹配,这意味着:

table:
name   | officeId (foreignkey)
--------
bob    | 1
alice  | 1 
alicia | 2
walter | 2

他希望沿着这些方向做点什么:

向我提供办公室(officeId)的所有记录,其中有

成员
ANY name ~ ANY[.*ob, ali.*]
meaning
ANY of[alicia, walter] ~ ANY of [.*ob, ali.*] results in true

我无法自己弄清楚:/。

修改

原始描述缺少真正的问题:

我无法使用select disctinct officeId .. where name ~ ANY[.*ob, ali.*],因为:

这个应用程序,将数据存储在postgres-xml列中,这意味着我确实有(在评估xpath('/data/clients/name/text()'))::text[]之后):

table:
name              | officeId (foreignkey)
-----------------------------------------
[bob, alice]      | 1
[anthony, walter] | 2
[alicia, walter]  | 3

有问题。并且“你不这样做,那太可怕了,为什么你会这样做,存储它就像存储在关系数据库中,用户使用基于文档的存储的无数据库,使用json”没有选择。

我坚持使用这个数据模型。

2 个答案:

答案 0 :(得分:0)

这看起来非常可怕,但我能想到做这种事情的唯一方法就是交叉连接和半连接的混合。在小数据集上,这可能会很好。在大型数据集上,我想交叉连接组件可能会让你非常努力。

检查一下,让我知道它是否与你的真实数据相符:

with patterns as (
  select unnest(array['.*ob', 'ali.*']) as pattern
)
select
  o.name, o.officeid
from
  office o
where exists (
  select null
  from patterns p
  where o.name ~ p.pattern
)

半联接可以帮助保护您免受类似“alicia nob”这样的名称的情况的影响,这些名称会遇到多种搜索模式,否则每次匹配都会回来。

答案 1 :(得分:0)

您可以将数组转换为文本。

SELECT * FROM workers WHERE (xpath('/data/clients/name/text()', xml_field))::text ~ ANY(ARRAY['wal','ant']);

将字符串数组转换为文本时,包含特殊字符或由关键字组成的字符串用双引号括起来,类似{jimmy,"walter, james"}两个条目。此外,当与~匹配时,它会与字符串的任何部分匹配,与LIKE匹配,而不是与整个字符串匹配。

以下是我在测试数据库中所做的事情:

test=# select id, (xpath('/data/clients/name/text()', name))::text[] as xss, officeid from workers WHERE (xpath('/data/clients/name/text()', name))::text ~ ANY(ARRAY['wal','ant']);
 id |           xss           | officeid 
----+-------------------------+----------
  2 | {anthony,walter}        |        2
  3 | {alicia,walter}         |        3
  4 | {"walter, james"}       |        5
  5 | {jimmy,"walter, james"} |        4
(4 rows)