关于json:jsonb键/值上的模式匹配

Pattern matching on jsonb key/value

我正在使用PostgreSQL 9.4。 我的表有一个jsonb列:

1
2
3
4
5
6
7
CREATE TABLE"PreStage".transaction (
  transaction_id serial NOT NULL,
  TRANSACTION jsonb
  CONSTRAINT pk_transaction PRIMARY KEY (transaction_id)
);

CREATE INDEX idxgin ON"PreStage".transaction USING gin (TRANSACTION);

我在JSONB列中按键/值存储事务。 其中一个要求是从键值中搜索客户名称,因此我运行的查询如下:

1
2
SELECT TRANSACTION AS DATA FROM"PreStage".transaction
WHERE  transaction->>('HCP_FST_NM') ilike ('%neer%');

我做什么似乎查询不喜欢GIN索引。 如何使查询使用不区分大小写模式搜索的GIN索引?

我尝试将jsonb列更改为文本,使用gin_trgm_ops对其进行索引,然后搜索所需的文本,然后将结果转换为json,然后搜索所需的键/值。 这种方法似乎不起作用。


默认的GIN索引运算符类jsonb_ops不允许对值进行全文模式匹配。细节:

  • 在Postgres jsonb中查询数组结构的正确索引是什么?

最佳索引策略取决于您的完整情况。有很多选择。要覆盖您提供的一个密钥,您可以使用功能性三元组索引。您已经测试过gin_trgm_ops,因此您已经熟悉了附加模块pg_trgm。对于那些不是:

  • PostgreSQL LIKE查询性能变化

安装模块后:

1
2
CREATE INDEX idxgin ON"PreStage".transaction
USING gin ((transaction->>'HCP_FST_NM') gin_trgm_ops);

然后支持此查询:

1
2
3
SELECT TRANSACTION AS DATA
FROM  "PreStage".transaction
WHERE  transaction->>'HCP_FST_NM' ILIKE '%neer%';

我还删除了一些不必要的括号。

根据未知的详细信息,有多种选项可以优化索引覆盖率。

例如,如果许多行根本没有键"HCP_FST_NM",那么将其作为部分索引以排除不相关的行并保持索引较小:

1
2
3
CREATE INDEX idxgin ON"PreStage".transaction
USING gin ((transaction->>'HCP_FST_NM') gin_trgm_ops)
WHERE TRANSACTION ? 'HCP_FST_NM';

?jsonb包含运算符。
并为每个应该使用此索引的查询添加相同的谓词:

1
2
3
4
SELECT TRANSACTION AS DATA
FROM  "PreStage".transaction
WHERE  transaction->>'HCP_FST_NM' ILIKE '%neer%'
AND    TRANSACTION ? 'HCP_FST_NM';  -- even if that seems redundant.