如何过滤 json 列中嵌套值的行?

Posted

技术标签:

【中文标题】如何过滤 json 列中嵌套值的行?【英文标题】:How to filter rows on nested values in a json column? 【发布时间】:2015-02-16 14:10:59 【问题描述】:

这是我的表格(简化,只有重要的列):

CREATE TABLE things (
  id serial primary key
, name varchar
, blueprint json default ''
);

还有一些示例数据:

# select * from things;

 id |  name   |                                  blueprint
----+---------+-----------------------------------------------------------------------------
  1 | Thing 1 | 
  2 | Thing 2 | "1":"name":"Iskapola","wight":"2"
  3 | Thing 3 | "1":"name":"Azamund","weight":"3", "2":"name":"Iskapola","weight":"1"
  4 | Thing 4 | "1":"name":"Ulamir","weight":"1", "2":"name":"Azamund","weight":"1"

我想选择在name 键下的任意位置具有'Azamund' 的行。 像这样的:

# select * from things where * ->> 'name' = 'Azamund';

 id |      blueprint
----+----------------------------------------------------------------------------
  7 | "1":"name":"Azamund","weight":"3", "2":"name":"Iskapola","weight":"1"
  8 | "1":"name":"Ulamir","weight":"1", "2":"name":"Azamund","weight":"1"

数据的嵌套与示例中的完全相同(只有一层)。 目前我们使用的是 PostgreSQL 9.3.5。

在 PostgreSQL 9.3 中可以吗?也许是 9.4?

【问题讨论】:

我不确定,但这可能会对您有所帮助***.com/questions/10560394/… 谢谢!我看到了那个问题...但是这里的区别-我不能写下name 列的关键路径...它可以在'1''9' 键下。我仍然应该能够找到它。无论如何-谢谢。我已经添加了更多有问题的细节以突出显示它......(希望它很清楚) 所以只有一层嵌套?此外,实际的表定义总是很有帮助。数据类型可能是textjsonjsonb? ...NOT NULL? @ErwinBrandstetter - 添加了有关表模式的更多信息。好吗? 我冒昧地整理了您的问题,因为我想我将来可能会提到它。我希望我抓住了要点? 【参考方案1】:

您的查询已结束。 json_each() 是关键功能。或jsonb_each()jsonb。一些改进:

SELECT *
FROM   things t
WHERE  EXISTS (
   SELECT FROM json_each(t.blueprint) b
   WHERE  b.value->>'name' ILIKE 'azamund'
   );

老sqlfiddledb小提琴here

json_each() 已经将值作为json 数据类型返回。无需额外演员。

更好的是,在EXISTS 中使用LATERAL 引用。这比使用SELECT 列表中的集合返回函数取消嵌套要干净得多。相关:

Call a set-returning function with an array argument multiple times

使用ILIKE (~~*) 进行模式匹配。正则表达式匹配(~~*)更强大,但也更昂贵。所以尽可能使用基本的LIKE / ILKE。详情:

Pattern matching with LIKE, SIMILAR TO or regular expressions in PostgreSQL

JSON 数组的替代方案

您已经看过我对 JSON 数组的相关回答:

How do I query using fields inside the new PostgreSQL JSON datatype?

虽然对嵌套 JSON 对象的查询看起来很简单,但对数组有出色的索引支持

Index for finding an element in a JSON array

在 Postgres 12 中使用 SQL/JSON 可能会变得更简单/更高效...

【讨论】:

不错的改进!谢谢。【参考方案2】:

我可以执行的最近查询(返回我需要的数据)是:

select *
from (select id, (json_each(blueprint)).value::json->>'name' as name
      from stocks) as t
where t.name ~* 'azamund';

嗯...也许有更好的东西?

【讨论】:

以上是关于如何过滤 json 列中嵌套值的行?的主要内容,如果未能解决你的问题,请参考以下文章

Spark Sql 查询嵌套记录。我想先过滤嵌套的记录数组,然后爆炸(将它们展开成行)

如何使用映射或过滤器而不是列表推导过滤特定值的嵌套字典(pythonic 方式)?

如何根据pyspark中的行和列条件过滤多行

PySpark - 如何根据列中的两个值从数据框中过滤出连续的行块

extjs 3.4.0 - 如何过滤读取 JSON 的存储

HBase:使用限定符和值的过滤器扫描时如何获得完整的行?