[postgis-users] How best to create and use associative array type in Postgres?
Regina Obe
lr at pcorp.us
Fri Jan 7 20:20:23 PST 2022
Oh forgot one more very useful operator, the subtraction operator. Removes a key/value from the list:
SELECT '{"color": "blue", "height_m": 10}'::jsonb - 'color'
Returns:
{"height_m": 10}
From: Regina Obe [mailto:lr at pcorp.us]
Sent: Friday, January 7, 2022 11:18 PM
To: 'PostGIS Users Discussion' <postgis-users at lists.osgeo.org>
Subject: RE: [postgis-users] How best to create and use associative array type in Postgres?
David,
Not sure what you are asking? There are many functions for jsonb and even more the newer your PostgreSQL is.
Take a look at - https://www.postgresql.org/docs/current/functions-json.html
You can pull arrays by index but not really key/values by index (because jsonb reorders keys/values for efficiency). So order shouldn’t matter in jsonb as the same level keys are unique.
The trick of using the concatenation operator (||) to update keys values works, because the last entry for a key wins, and any key not in the list gets replaced by the last one. So I guess your popping idea
Take for example:
SELECT '{"color": "blue", "height_m": 10}'::jsonb || '{"color": "red"}'::jsonb || '{"width_m": 5}';
Returns:
{"color": "red", "width_m": 5, "height_m": 10}
Note how the entry width_m was added, but not the order you specified it, and that the color was changed from blue to red.
Now if you wanted to get a set of all the key value pairs, you’d use jsonb_each_text (to get value as text) or jsonb_each to get the value as a jsonb.
Here is an example:
WITH a AS (SELECT '{"color": "blue", "height_m": 10}'::jsonb || '{"color": "red"}'::jsonb || '{"width_m": 5}' AS data)
SELECT kv.*
FROM a, jsonb_each_text(a.data) AS kv;
Returns:
color red
width_m 5
height_m 10
Now lets do this with PostGIS :)
WITH a AS (
SELECT ST_AsGeoJSON(ST_MakeLine( ARRAY[ST_Point(1,2), ST_Point(3,4), ST_Point(-9,1)]))::jsonb AS data
)
SELECT kv.key, kv.value, kv.value->2->>0 AS last_x
FROM a, jsonb_each(a.data) AS kv;
key | value | last_x
-------------+---------------------------+--------
type | "LineString" |
coordinates | [[1, 2], [3, 4], [-9, 1]] | -9
(2 rows)
From: postgis-users [mailto:postgis-users-bounces at lists.osgeo.org] On Behalf Of Shaozhong SHI
Sent: Friday, January 7, 2022 9:25 PM
To: PostGIS Users Discussion <postgis-users at lists.osgeo.org <mailto:postgis-users at lists.osgeo.org> >
Subject: Re: [postgis-users] How best to create and use associative array type in Postgres?
Hi, Regina,
That is interesting!
How to add new entries to the dictionary. E.g., weight: 40?
Can the dictionary to serve as a collection of paired key, value set, so that we can accumulate data to be processed?
Then, we can deal with the first, then 2nd and so on in turn?
Or, we can do things like pip and pop? Namely, when we have dealt with the first key, value pair, it will be out the dictionary, so that we can be sure that we are dealing with each key, value pair in turn?
Alternatively, can we fetch each key, value pair by its index or position?
Regards,
David
On Fri, 7 Jan 2022 at 21:19, Regina Obe <lr at pcorp.us <mailto:lr at pcorp.us> > wrote:
Use JSONB datatype.
CREATE TABLE test(id integer, data jsonb);
TRUNCATE tABLE test;
INSERT INTO test(id, data)
VALUES (1, '{"color": "red", "height_m": 10}');
-- PG14 or higher – you can used subscript feature
UPDATE test SET data['color'] = to_jsonb('blue'::text),
data['height_m'] = to_jsonb(10), data['width_m'] = to_jsonb(2)
WHERE id = 1;
-- PG14 or lower
UPDATE test SET data = jsonb_set(data, ARRAY['color'], to_jsonb('blue'::text), true)
WHERE id = 1;
-- PG14 or lower to set multiple
UPDATE test SET data = data || '{"color": "blue", "height_m": 10}'::jsonb;
-- To read (all versions)
SELECT data->>'color' AS color, (data->>'height_m')::integer As height_m
FROM test;
From: postgis-users [mailto:postgis-users-bounces at lists.osgeo.org <mailto:postgis-users-bounces at lists.osgeo.org> ] On Behalf Of Shaozhong SHI
Sent: Wednesday, January 5, 2022 1:30 PM
To: PostGIS Users Discussion <postgis-users at lists.osgeo.org <mailto:postgis-users at lists.osgeo.org> >
Subject: [postgis-users] How best to create and use associative array type in Postgres?
In Oracle, one can create and use associative array. For instance,
TYPE FID_MEASURE IS TABLE OF NUMBER INDEX BY VARCHAR2(38);
NODES_WAITING FID_SET;
How best to create and use associative array type in Postgres?
Or, what is the best/most efficient equivalent in Postgres?
Regards,
David
_______________________________________________
postgis-users mailing list
postgis-users at lists.osgeo.org <mailto:postgis-users at lists.osgeo.org>
https://lists.osgeo.org/mailman/listinfo/postgis-users
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/postgis-users/attachments/20220107/7e16f769/attachment.html>
More information about the postgis-users
mailing list