我有一个带有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()
答案 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。