Postgres 9.2
I quote Andrew Dunstan on the pgsql-hackers list:
At some stage there will possibly be some json-processing (as opposed
to json-producing) functions, but not in 9.2.
Doesn't prevent him from providing an example implementation in PLV8 that should solve your problem. (Link is dead now, see modern PLV8 instead.)
Postgres 9.3
Offers an arsenal of new functions and operators to add "json-processing".
The answer to the original question in Postgres 9.3:
For a given table:
CREATE TABLE json_tbl (data json);
Query:
SELECT object
FROM json_tbl
, json_array_elements(data) AS object
WHERE object->>'name' = 'Toby';
Advanced example:
For bigger tables you may want to add an expression index to increase performance:
Postgres 9.4
Adds jsonb
(b for "binary", values are stored as native Postgres types) and yet more functionality for both types. In addition to expression indexes mentioned above, jsonb
also supports GIN, btree and hash indexes, GIN being the most potent of these.
The manual goes as far as suggesting:
In general, most applications should prefer to store JSON data as
jsonb
, unless there are quite specialized needs, such as legacy
assumptions about ordering of object keys.
Bold emphasis mine.
Also, performance benefits from general improvements to GIN indexes.
Postgres 9.5
Complete jsonb
functions and operators. Add more functions to manipulate jsonb
in place and for display.
Functionality and performance has been improved with every major Postgres version since. It's pretty complete by now (as of Postgres 16). One major, notable addition in ...
Postgres 12
... is the SQL/JSON path language along with operators and functions. The answer to the example in the question can now be, for a given table (with jsonb
):
CREATE TABLE jsonb_tbl (data jsonb);
SELECT jsonb_path_query_first(data, '$[*] ? (@.name == "Toby")') AS object
FROM jsonb_tbl
WHERE data @> '[{"name": "Toby"}]'; -- optional, for index support
Or equivalent:
...
WHERE data @@ '$[*].name == "Toby"';
fiddle
See:
About indexing: