Can't find record filter by zero array item - postgresql-9.5

my_column has type jsonb
here json
{
"id": 4107,
"states": [
{
"dt": "2020-11-06T10:24:30.277+0000",
"id": "order.new"
}
]
}
I need to find all records where states[0].id="order.new" (zero item in array)
I try this
SELECT * FROM history WHERE my_column #> '{states,0, id}'= 'order.new'
limit 10
But I get error:
ERROR: invalid input syntax for type json
LINE 1: SELECT * FROM history WHERE my_column #> '{states,0, id}'= 'or...

The #> operator tests whether the right operand is contained in the left operand. The right operand must be valid Json document or a literal, that's why you're getting a syntax error.
The operator you want is #>, which uses the array as the path for extraction:
# SELECT * FROM history WHERE my_column #> '{states,0, id}' = '"order.new"'
limit 10;
id | my_column
----+-------------------------------------------------------------------------------------
1 | {"id": 4107, "states": [{"dt": "2020-11-06T10:24:30.277+0000", "id": "order.new"}]}
(1 row)
With the #> operator you could do the following, but it would be checking for matching elements in any array position, not only index 0:
# SELECT * FROM history WHERE my_column #> '{"states": [{ "id": "order.new" }]}';
id | my_column
----+-------------------------------------------------------------------------------------------------------------------------------------------------
1 | {"id": 4107, "states": [{"dt": "2020-11-06T10:24:30.277+0000", "id": "order.new"}]}
4 | {"id": 4107, "states": [{"dt": "2020-11-06T10:24:30.333+0000", "id": "order.test"}, {"dt": "2020-11-06T10:24:33.333+0000", "id": "order.new"}]}

Related

LIKE in Array of Objects in JSONB column

I have JSONB data in a Postgres column like this:
{
"Id": "5c6d3210-1def-489b-badd-2bcc4a1cda28",
"Name": "Jane Doe",
"Tags": [
{
"Key": "Project",
"Value": "1004345"
}
]
}
How can I query data where Name contains "Jane" or "Tags.Key" contains "4345"?
I tried this but this only matches the exact "Key" value:
select * from documents where data->'Tags' #> '[{ "Value":"1004345"}]';
You can use a JSON path operator using like_regex
select *
from documents
where data ## '$.Tags[*].Value like_regex "4345"'
you can do this way
select *
from documents
where 'Tags' ->> 'Value' = '1004345';

Check if row contains a nested item in DynamoDB?

I am trying to use PartiQL with DynamoDB to perform SQL queries to check if a device is inactive and contains an error. Here's is the query I am using:
SELECT *
FROM "table"
WHERE "device"."active" = 0 AND "device"."error" IS NOT NULL
However I've noticed that even if a device doesn't have the error item, the query still returns a row. How can I query a device that only contains the error item?
With error item
{
"id": "value",
"name": "value,
"device": {
"active": 0,
"error": {
"reason": "value"
}
}
}
Without error item
{
"id": "value",
"name": "value,
"device": {
"active": 0
}
}
You're looking for IS NOT MISSING :) That's the partiql version of the filter expression operator function attribute_exists.
Given a table with a primary key PK, sort key SK, and the following data:
PK
SK
myMap
foo
1
{}
foo
2
{"test": {}}
-- Returns both foo 1 and foo 2
SELECT *
FROM "my-table"
WHERE "PK" = 'foo' AND "myMap"."test" IS NOT NULL
-- Returns just foo 2
SELECT *
FROM "my-table"
WHERE "PK" = 'foo' AND "myMap"."test" IS NOT MISSING
Also made sure my example specifies the PK in the WHERE clause - otherwise, your query will be a full scan. Maybe that's what you want, though. Just something to be aware of.

Creating NUMERIC array from JSONB data in Postgres

I have a Postgres JSONB data which contains an ARRAY of type NUMERIC. I want to extract this ARRAY and store it in a variable of type NUMERIC[]. Here's is my JSONB object.
{
"userIds": [
101,102,103
],
"userRole": {
"id": "1",
"name": "Administrator"
}
}
How can I extract userIds from this JSONB object and store them in NUMERIC[] as I have to iterate on this NUMERIC[]?
Any help would be highly appreciated.
One way is to extract the ids with jsonb_array_elements, parse them to the right data type and aggregate them again in an array, e.g.:
SELECT array_agg(id) FROM (
SELECT
(jsonb_array_elements('{
"userIds": [101,102,103],
"userRole": {
"id": "1",
"name": "Administrator"
}
}'::jsonb->'userIds')::numeric)) j(id);
array_agg
---------------
{101,102,103}
(1 row)
If you want to iterate over these values as rows in your resultset, don't bother with the outer query:
SELECT
jsonb_array_elements('{
"userIds": [101,102,103],
"userRole": {
"id": "1",
"name": "Administrator"
}}'::jsonb->'userIds')::numeric;
jsonb_array_elements
----------------------
101
102
103
(3 rows)

Query a column with jsonb data meeting certain criteria

Problem
I have a table like this:
product
tags (jsonb)
P001
[{"name": "LX","active": true}, {"name": "TX","active": true}]
P002
[{"name": "LX","active": true}]
I am trying to query against this table to get a list of products with tags that are the same.
I found the following to be insufficient for my query since it will match all products with at least the tag I query for:
SELECT product
FROM product_table
WHERE tags #> '[
{"name": "LX","active": true}
]';
Result
product
P001
P002
So I need the match to be more exact without being so strict as to demand order of tag objects in the array. For example:
[
{
"name": "LX",
"active": true
},
{
"name": "TX",
"active": true
}
]
-- Interpreted the same as
[
{
"name": "TX",
"active": true
},
{
"name": "LX",
"active": true
}
]
Desired Result
A list of products that match only the tags in the query.
Resources
A list of the resources I am using to try and solve the problem.
9.16. JSON Functions and Operators
How To Query a JSONB Array of Objects as a Recordset in PostgreSQL
Working with a JSONB Array of Objects in PostgreSQL
Base on the example you give, you can use simultaneous containment in both directions.
...WHERE tags <# :whatever and tags #> :whatever
If you don't like repeating the arguments, you could make a custom function, or operator:
create function equal_but_for_order(jsonb,jsonb) returns boolean language sql as $$
select $1 <# $2 and $1 #> $2
$$;
create operator <#> (function = equal_but_for_order, leftarg = jsonb, rightarg=jsonb);
...WHERE tags <#> :whatever

postgresql search jsonb array items

I want to find rows base on data in the jsonb data type column with postgresql, is this the correct syntax to do search with array items?
SELECT * FROM table
WHERE diff_data #> '{"rfc6902": [{"op": "replace", "path": "/status/"}, "value": "0"]}';
output first row in below table
table
id | diff_data
1 | {"rfc6902": [{"op": "replace", "path": "/status", "value": "0"}]}
2 | {"rfc6902": [{"op": "replace", "path": "/status", "value": "1"}]}