如何在PostgreSQL hstore中使用通配符查询值

Rob*_*lez 17 postgresql hstore

我正在尝试查询hstore以查找与搜索条件匹配的某个键的所有值.

我可以获得某个键的所有值,如下所示:

SELECT DISTINCT
svals(slice(data, ARRAY['Supplier']))
FROM "products"
Run Code Online (Sandbox Code Playgroud)

我也可以得到一个特定的价值:

SELECT DISTINCT
svals(slice(data, ARRAY['Supplier'])) AS sup
FROM "products"
WHERE data @> 'Supplier => Toshiba'
Run Code Online (Sandbox Code Playgroud)

我真正喜欢的是(这不起作用):

SELECT DISTINCT
svals(slice(data, ARRAY['Supplier'])) AS sup
FROM "products"
WHERE data @> 'Supplier => %tosh%'
Run Code Online (Sandbox Code Playgroud)

要么:

SELECT DISTINCT
svals(slice(data, ARRAY['Supplier'])) AS sup
FROM "products"
WHERE lower(sup)
LIKE '%tosh%'
Run Code Online (Sandbox Code Playgroud)

用于不区分大小写的搜索.这是怎么做到的?

wil*_*ynn 33

您可以hstore使用->运算符从列中按键提取值.

SELECT data->'Supplier' AS sup
FROM products
WHERE lower(data->'Supplier') LIKE '%tosh%';
Run Code Online (Sandbox Code Playgroud)

另外,像PostgreSQL中的大多数表达式(除了类似的东西random()),你可以索引这个值:

CREATE INDEX products_supplier_key ON products ((data->'Supplier'));
CREATE INDEX products_supplier_lowercase_key ON products ((lower(data->'Supplier')));
Run Code Online (Sandbox Code Playgroud)

这将允许PostgreSQL使用索引回答许多此类查询,而不是获取每一行并扫描hstore列.请参阅LIKE关于索引使用情况的索引类型说明.

  • 第一个答案:没有.每个密钥都需要在一个单独的索引中(假设你需要B树,你可以为这种匹配做),并且添加大量索引通常是个坏主意. (3认同)
  • 第二个答案:[确定,为什么不](https://gist.github.com/3759322).PostgreSQL数据结构本身由数据结构表示,PostgreSQL允许您运行程序,因此您可以执行任何您想要的操作.将它包裹在"执行立即"中 - 或者更糟糕的是,将其折叠成触发器 - 留给读者练习. (2认同)

jre*_*urn 8

对于任何在未来看到这一点的人来说,willglynn的答案有一点需要注意 - 原始查询和新查询的行为略有不同.也就是说,

SELECT data->'Supplier' AS sup
FROM products;
Run Code Online (Sandbox Code Playgroud)

将包含NULL值,假设至少有一行没有供应商的分配.

SELECT DISTINCT
svals(slice(data, ARRAY['Supplier']))
FROM "products"
Run Code Online (Sandbox Code Playgroud)

不会返回NULL值.