Rails中的JSONB查询包含一个包含哈希数组的键

时间:2017-01-17 17:34:09

标签: ruby-on-rails postgresql activerecord ruby-on-rails-5 jsonb

我有一个带有content模型的Rails 5项目,该项目具有JSONB列#<Page id: 46, content: {..., "media" => [{ "resource_id" => 143, "other_key" => "value", ...}, ...], ...}> 。所以结构看起来像这样(减少到问题的最低限度):

resource_id

如何在media JSONB列的content键下编写查询以查找Page.where("content -> 'media' @> ?", {resource_id: '143'}.to_json)所需数字的所有页面?这是我做的一个不起作用的尝试(我想因为在数组的每个项目中还有其他键/值对): Page.where("content -> 'media' -> 0 ->> 'resource_id' = ?", '143')

编辑:这有效,但只检查媒体数组中的第一个哈希:row()

1 个答案:

答案 0 :(得分:3)

使用sql,这应该为您提供资源ID为143的所有页面:

select * from pages p where '{"resource_id": 143}' <@ ANY ( ARRAY(select jsonb_array_elements ( content -> 'media' ) from pages where id=p.id ) );

Postgresql有一个名为ANY(postgres docs)的函数,它使用expression operator ANY (array)形式。评估左侧表达式并使用给定运算符与数组的每个元素进行比较。

由于ANY的右侧参数必须是数组(不是json数组),我们使用jsonb_array_elements方法将content-&gt; media json数组转换为一组行,然后将这些行转换为数组使用ARRAY()。

<@运算符检查右侧的表达式是否包含左侧的表达式。例如:'{"a": 1}'::jsonb <@ '{"b": 2, "a": 1}'::jsonb将返回true。