有效地搜索整个 1 级嵌套 JSONB

Kam*_*ski 3 postgresql json postgresql-9.5

假设我们需要检查 jsonb 列是否包含与任何值(非嵌套,仅第一级)中的子字符串匹配的特定值。

如何有效地优化查询以搜索JSONB每个值的整个列?

是否有一些好的替代方法可以替代转换ILIKE %val%为文本的 jsonb 数据类型?

jsonb_each_text(jsonb_column) ILIKE '%val%'
Run Code Online (Sandbox Code Playgroud)

例如,考虑以下数据:

SELECT '{"col1": "somevalue", "col2": 5.5, "col3": 2016-01-01, "col4": "othervalue", "col5": "yet_another_value"}'::JSONB
Run Code Online (Sandbox Code Playgroud)

当需要%val%在列中包含不同键配置的记录中搜索模式时,您将如何优化这样的查询?是否有更好的替代方法来将每个键值对提取为文本并执行 ILIKE/POSIX 搜索?

主要是,我正在寻找一种不同的替代方法来将整个 jsonb 字段解压缩到单独的键行中,它们的值为 text

Erw*_*ter 6

对于模式匹配,目前(第 10 页)没有比取消嵌套值并单独测试每个值更好的使用标准运算符和索引的方法。至少,使用一个有效的EXISTS查询:

SELECT *
FROM   tbl
WHERE  EXISTS (SELECT FROM jsonb_each_text(jsonb_column) WHERE value ~* 'val');
Run Code Online (Sandbox Code Playgroud)

专门溶液对于该特定的用例:串接每行的所有字符串值与IMMUTABLE功能,并创建上表达的卦GIN索引。您需要pg_trgm安装附加模块。如果您不熟悉,请先阅读以下内容:

功能:

CREATE OR REPLACE FUNCTION f_all_value_string(jsonb)
  RETURNS text AS
$func$
SELECT string_agg(value, '|') FROM jsonb_each_text($1)
$func$  LANGUAGE sql IMMUTABLE;
Run Code Online (Sandbox Code Playgroud)

选择一个永远不会干扰您的模式的分隔符 - '|' 在示例中。

指数:

CREATE INDEX tbl_all_value_string_trigram_idx ON tbl
USING GIN (f_all_value_string(jsonb_column) gin_trgm_ops); 
Run Code Online (Sandbox Code Playgroud)

查询(匹配索引):

SELECT * FROM tbl WHERE f_all_value_string(jsonb_column) ~* 'val';
Run Code Online (Sandbox Code Playgroud)

有关的:


归档时间:

查看次数:

2465 次

最近记录:

7 年,5 月 前