在 jsonb_array_elements(二维数组)中搜索元素
Searching element in jsonb_array_elements(2D array)
我有一个 table 有 2 列 R(id int,dat jsonb)。 b 列 jsonb 由一个二维数组 [][] 组成。例如:
id| dat
1 | {"name":"a","numbers":[[1,2],[3,4],[5,6],[1,3]]}
2 | {"age":5,"numbers":[[1,1]]}
3 | {"numbers":[[5,6],[6,7]]}
我正在尝试在其中一个子数组中查找包含特定数字的所有 ID。我使用了 2 个解决方案,我想了解为什么第一个不起作用:
1)
select * from R
where exists (
select from jsonb_array_elements(R.dat->'numbers')->>0 first,jsonb_array_elements(range.data->'numbers')->>1 second where first::decimal= 1 and second::decimal= 1
);
ERROR: syntax error at or near "->>"
LINE 3: ...t from jsonb_array_elements(R.dat->'numbers')->>0 first,j...
SELECT *
FROM R
WHERE EXISTS (
SELECT FROM jsonb_array_elements(R.dat-> 'numbers') subarray
WHERE (subarray->>0)::decimal = 1 and (subarray->>1)::decimal = 1
);
此外,我看到 gin 索引不处理这个运算符,所以基本上任何索引都可以帮助这里吗?
您的第一个查询会引发错误,因为您只能在 FROM
子句中使用 table experssions(不能使用值表达式)。
您可以使第二个查询更简单一些:
select *
from r
where exists (
select from jsonb_array_elements(dat->'numbers') subarray
where subarray = '[1,1]'
);
或在横向连接中使用函数:
select r.*
from r
cross join jsonb_array_elements(dat->'numbers')
where value = '[1,1]';
由于使用了 jsonb_array_elements()
,因此没有索引可以支持这些查询。
您可能想像这样使用包含运算符 @>
:
select *
from r
where dat->'numbers' @> '[[1,1]]'::jsonb
id | dat
----+------------------------------------------------------------
1 | {"name": "a", "numbers": [[1, 2], [3, 4], [5, 6], [1, 3]]}
2 | {"age": 5, "numbers": [[1, 1]]}
(2 rows)
不幸的是,如您所见,它并没有像您预期的那样工作。在数组上使用运算符有点棘手,因为它的工作方式是:如果 array2
的每个元素 j
都有一个 i
,则 array1 @> array2
为真在 array1
中使得 i @> j
。因此,根据 the documentation:
the order of array elements is not significant when doing a containment match, and duplicate array elements are effectively considered only once.
我有一个 table 有 2 列 R(id int,dat jsonb)。 b 列 jsonb 由一个二维数组 [][] 组成。例如:
id| dat
1 | {"name":"a","numbers":[[1,2],[3,4],[5,6],[1,3]]}
2 | {"age":5,"numbers":[[1,1]]}
3 | {"numbers":[[5,6],[6,7]]}
我正在尝试在其中一个子数组中查找包含特定数字的所有 ID。我使用了 2 个解决方案,我想了解为什么第一个不起作用:
1)
select * from R
where exists (
select from jsonb_array_elements(R.dat->'numbers')->>0 first,jsonb_array_elements(range.data->'numbers')->>1 second where first::decimal= 1 and second::decimal= 1
);
ERROR: syntax error at or near "->>"
LINE 3: ...t from jsonb_array_elements(R.dat->'numbers')->>0 first,j...
SELECT *
FROM R
WHERE EXISTS (
SELECT FROM jsonb_array_elements(R.dat-> 'numbers') subarray
WHERE (subarray->>0)::decimal = 1 and (subarray->>1)::decimal = 1
);
此外,我看到 gin 索引不处理这个运算符,所以基本上任何索引都可以帮助这里吗?
您的第一个查询会引发错误,因为您只能在 FROM
子句中使用 table experssions(不能使用值表达式)。
您可以使第二个查询更简单一些:
select *
from r
where exists (
select from jsonb_array_elements(dat->'numbers') subarray
where subarray = '[1,1]'
);
或在横向连接中使用函数:
select r.*
from r
cross join jsonb_array_elements(dat->'numbers')
where value = '[1,1]';
由于使用了 jsonb_array_elements()
,因此没有索引可以支持这些查询。
您可能想像这样使用包含运算符 @>
:
select *
from r
where dat->'numbers' @> '[[1,1]]'::jsonb
id | dat
----+------------------------------------------------------------
1 | {"name": "a", "numbers": [[1, 2], [3, 4], [5, 6], [1, 3]]}
2 | {"age": 5, "numbers": [[1, 1]]}
(2 rows)
不幸的是,如您所见,它并没有像您预期的那样工作。在数组上使用运算符有点棘手,因为它的工作方式是:如果 array2
的每个元素 j
都有一个 i
,则 array1 @> array2
为真在 array1
中使得 i @> j
。因此,根据 the documentation:
the order of array elements is not significant when doing a containment match, and duplicate array elements are effectively considered only once.