检查 JSONB 列中的数组是否包含另一个数组中的任何值
Check whether array in JSONB column includes any of the values in another array
问题
查找示例数据中的所有记录,其中 foo->bar
至少包含给定数组中的一项,例如[1,2]
示例数据
Record 1 => 'foo': {
'bar': [1,2]
}
Record 2 => 'foo': {
'bar': [3,4]
}
Record 3 => 'foo': {
'bar': [5,7]
}
Record 4 => 'foo': {
'bar': [1]
}
Record 5 => 'foo': {
'bar': [2,3]
}
预期结果
Record 1 => 'foo': {
'bar': [1,2]
}
Record 4 => 'foo': {
'bar': [1]
}
Record 5 => 'foo': {
'bar': [2,3]
}
我尝试使用运算符 @>
和 ?|
,仅当包含所有项目时才首先检查 JSOB 和 returns。第二个问题与类型 JSOB => Integer[]
SQL
SELECT "some_table".* FROM "some_table" WHERE (foo->'bar' @> '[1,2]'::jsonb);
Rails 范围
scope :for_bar, -> (bars) { where("foo->'bar' @> ?::jsonb", bars.to_json) }
解决这个问题的任何建议。
一种可能的解决方案是使用 jsonb_array_elements()
将 JSON 数组展开成集合。然后,在 EXISTS
子查询中,将这些集合内部连接到公共元素上。
SELECT *
FROM some_table
WHERE EXISTS (SELECT *
FROM jsonb_array_elements(some_table.foo->'bar') t (v)
INNER JOIN jsonb_array_elements('[1,2]'::jsonb) s (v)
ON t.v = s.v);
我想你需要的是:
- 从 foo 中提取 bar,
- 将任何元素从
bars
映射到 JSON,
- 将绑定值转换为
array
、
- 将绑定值数组转换为
jsonb[]
、
- 检查左 JSON 值的
any
是否包含右 JSON path/value 条目在顶层 (@>
):
SomeTable.where("foo->'bar' @> ANY(ARRAY[?]::JSONB[])", [1, 2].map(&:to_json))
问题
查找示例数据中的所有记录,其中 foo->bar
至少包含给定数组中的一项,例如[1,2]
示例数据
Record 1 => 'foo': {
'bar': [1,2]
}
Record 2 => 'foo': {
'bar': [3,4]
}
Record 3 => 'foo': {
'bar': [5,7]
}
Record 4 => 'foo': {
'bar': [1]
}
Record 5 => 'foo': {
'bar': [2,3]
}
预期结果
Record 1 => 'foo': {
'bar': [1,2]
}
Record 4 => 'foo': {
'bar': [1]
}
Record 5 => 'foo': {
'bar': [2,3]
}
我尝试使用运算符 @>
和 ?|
,仅当包含所有项目时才首先检查 JSOB 和 returns。第二个问题与类型 JSOB => Integer[]
SQL
SELECT "some_table".* FROM "some_table" WHERE (foo->'bar' @> '[1,2]'::jsonb);
Rails 范围
scope :for_bar, -> (bars) { where("foo->'bar' @> ?::jsonb", bars.to_json) }
解决这个问题的任何建议。
一种可能的解决方案是使用 jsonb_array_elements()
将 JSON 数组展开成集合。然后,在 EXISTS
子查询中,将这些集合内部连接到公共元素上。
SELECT *
FROM some_table
WHERE EXISTS (SELECT *
FROM jsonb_array_elements(some_table.foo->'bar') t (v)
INNER JOIN jsonb_array_elements('[1,2]'::jsonb) s (v)
ON t.v = s.v);
我想你需要的是:
- 从 foo 中提取 bar,
- 将任何元素从
bars
映射到 JSON, - 将绑定值转换为
array
、 - 将绑定值数组转换为
jsonb[]
、 - 检查左 JSON 值的
any
是否包含右 JSON path/value 条目在顶层 (@>
):
SomeTable.where("foo->'bar' @> ANY(ARRAY[?]::JSONB[])", [1, 2].map(&:to_json))