jsonb 列上的索引模式

问题描述 投票:0回答:1

我想使用 jsonb 列上的 GIN 索引进行模式匹配来提高查询性能

例如,我有一个表定义为:

CREATE TABLE my_table (
  uuid text,
  doc jsonb
);

表doc的每一行都有路径{A,B}。 B 是一个对象,可能是空的。路径中多了一个可选元素:可以不存在,也可以是C、D等

我可以为模式匹配创建一个将在下面列出的所有情况下使用的索引吗?

SELECT doc#>>'{A,B}'
FROM my_table
WHERE doc#>>'{A,B}' ILIKE '%example%';
SELECT doc#>>'{A,B,C}'
FROM my_table
WHERE doc#>>'{A,B,C}' ILIKE '%example%';
SELECT doc#>>'{A,B,D}'
FROM my_table
WHERE doc#>>'{A,B,D}' ILIKE '%example%';

我尝试将索引创建为:

CREATE INDEX my_index
ON my_table
USING GIN ((doc#>>'{A,B}') gin_trgm_ops)

不幸的是,它仅适用于路径为 {A,B} 的查询,而不适用于 {A,B,C}

postgresql indexing pattern-matching jsonb
1个回答
0
投票

一个索引可能适用于所有情况,但对于与索引表达式不完全匹配的索引,您必须以一种不自然的方式编写查询:

SELECT doc#>>'{A,B,C}'
FROM my_table
WHERE doc#>>'{A,B}' ILIKE '%example%' AND doc#>>'{A,B,C}' ILIKE '%example%';

doc#>>'{A,B,C}' ILIKE '%example%'
通常意味着
doc#>>'{A,B}' ILIKE '%example%'
,但这不是 PostgreSQL 会为你推理出来的。这也并非在所有情况下都完全正确,如果一个的最终结果是字符串化的 JSON 对象,而另一个只是普通字符串,则需要在 JSON 中转义的字符将在
doc#>>'{A,B}'
中转义,但不会在
doc#>>'{A,B,C}'
中转义。

select '{"0":{"a":"b\"c"}}'::jsonb #>> '{0}';
---------------
 {"a": "b\"c"}

select '{"0":{"a":"b\"c"}}'::jsonb #>> '{0,a}';
----------
 b"c
© www.soinside.com 2019 - 2024. All rights reserved.