The tricky thing here is that filters is an array, so you can’t do the query directly, you have to scroll to each position of it.
For this, you must use the function jsonb_array_elements(jsonb)
. It will turn the results list into a "table" and you can give work with these results.
Imagine you have instead of 1 element inside filters, have 2 elements. Example:
'{"filtros":[
{
"tipo":"caracteristicas",
"operador":"=",
"valor":{"18":[12]}
},
{
"tipo":"caracteristicas",
"operador":"=",
"valor":{"19":[12]}
}
]}'
With (opcoes->>'filtros')::jsonb
you will choose all elements of this array. With jsonb_array_elements
you will turn it into tuples:
SELECT jsonb_array_elements((opcoes->>'filtros')::jsonb) FROM pagina limit 1;
jsonb_array_elements
---------------------------------------------------------------------
{"tipo": "caracteristicas", "valor": {"18": [12]}, "operador": "="}
{"tipo": "caracteristicas", "valor": {"19": [12]}, "operador": "="}
(2 rows)
But you still have to see if one of these guys has the "18" value. I imagine you wanted to look specifically at the field valor
and not any field. For this you have to reference it in the query:
SELECT jsonb_array_elements((opcoes->>'filtros')::jsonb)->>'valor' FROM pagina limit 1;
?column?
--------------
{"18": [12]}
{"19": [12]}
(2 rows)
Now just see if the "value" has the '18' key using the operator ?
(always remembering that you have to turn the result into a jsonb to allow the query).
SELECT (jsonb_array_elements((opcoes->>'filtros')::jsonb)->>'valor')::jsonb ? '18' FROM pagina limit 1;
?column?
--------------
t
f
(2 rows)
Since this result can return more than one row for each stored tuple, you can place it on a sub-allowance to make the filter, something like:
SELECT opcoes FROM pagina WHERE id in (
SELECT DISTINCT id FROM pagina WHERE
(jsonb_array_elements((opcoes->>'filtros')::jsonb)->>'valor')::jsonb ? '18'
);
Parts worked, but when I tried to use SELECT (jsonb_array_elements((options->'filters')::jsonb)->'value')::jsonb ? '18' FROM page limit 1; which for my case would be the most appropriate it returns error: ERROR: input syntax is invalid for type json DETAIL: End of expected input, found ",". CONTEXT: given JSON, line 1: 1,...
– Gabriel Schmidt Cordeiro
What prints the query: SELECT (jsonb_array_elements(((options->'filters')::jsonb)->>'value' ) FROM page limit 1;
– Begnini
Yes, this worked, but the problem was how much I tried to filter through the 18 record as you put in the penultimate SQL
– Gabriel Schmidt Cordeiro
I wanted to see the result of this query, because what it seems to be talking about is that the json contained in value is invalid.
– Begnini
I was able to solve it in a different way by doing so: SELECT options FROM page WHERE options::jsonb @> '{"filters":[{"value":{"18":[]}}]}'; but what you gave me helped me to get to the solution
– Gabriel Schmidt Cordeiro