问题
I have an array of objects that looks like this within the jsonb value
column of a table:
"west": [
{"id": "aa92f346-7a93-4443-949b-4eab0badd983", "version": 1},
{"id": "cd92e346-6b04-3456-050a-5eeb0bddd027", "version": 3}
]
I'm aiming to remove certain objects from this array based on their id and version like so:
SELECT value::jsonb #- '{west, 1}' FROM game.settings;
However, the 1
should not be hard-coded, but rather should equal the position of the object within the array which matches the id and version I'm looking for (in this case "id": "cd92e346-6b04-3456-050a-5eeb0bddd027", "version": 3
).
How would I go about determining this array position and passing it into the spot my hard-coded 1
currently holds?
回答1:
Example data:
create temp table settings as
select
'{"west": [
{"id": "aa92f346-7a93-4443-949b-4eab0badd983", "version": 1},
{"id": "cd92e346-6b04-3456-050a-5eeb0bddd027", "version": 3}
]}'::jsonb as value;
You can use jsonb_array_elements() with ordinality to determine the array position of a given element:
select elem, position
from settings, jsonb_array_elements(value->'west') with ordinality arr(elem, position)
where elem->>'id' = 'cd92e346-6b04-3456-050a-5eeb0bddd027';
elem | position
--------------------------------------------------------------+----------
{"id": "cd92e346-6b04-3456-050a-5eeb0bddd027", "version": 3} | 2
(1 row)
Use position
to remove the object from the array:
select value #- array['west', (position- 1)::text] new_value
from settings, jsonb_array_elements(value->'west') with ordinality arr(elem, position)
where elem->>'id' = 'cd92e346-6b04-3456-050a-5eeb0bddd027';
new_value
--------------------------------------------------------------------------
{"west": [{"id": "aa92f346-7a93-4443-949b-4eab0badd983", "version": 1}]}
(1 row)
来源:https://stackoverflow.com/questions/38640168/find-position-of-object-in-postgres-jsonb-array