Database Administrators Stack Exchange is a question and answer site for database professionals who wish to improve their database skills and learn from others in the community. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a field called 'user' that holds a json array that roughly looks like this:

"user":

[{ "_id" : "1", "count" : "4" }, { "_id" : "3", "count": "4"}]

Now I want a query like:

select count from tablename where id = "1"

I'm not able to get the particular field count from an array of json objects in PostgreSQL 9.4.

share|improve this question

It would be much more efficient to store your values in a normalized schema. That said, you can also make it work with your current setup.

Assumptions

Assuming this table definition:

CREATE TABLE tbl (tbl_id int, usr jsonb);

"user" is a reserved word and would require double quoting to be used as column name. Don't do that. I'm naming the column usr instead.

Query

The query is not as trivial as the comments make it seem:

SELECT tbl_id, obj.value->>'count' As count
FROM  (
   SELECT tbl_id, usr
   FROM   tbl
   WHERE  usr @> '[{"_id":"1"}]'
   ) u
JOIN LATERAL jsonb_array_elements(usr) obj(value) ON obj.value->>'_id' = '1';

There are three basic steps:

  1. Find qualifying rows (quickly!).

Note how usr @> '[{"_id":"1"}]' can find objects in the array with any number of additional keys.

You can support this with a generic GIN index on the JSON column, or with the more specialized operator class jsonb_path_ops:

CREATE INDEX tbl_usr_gin_idx ON tbl
USING  gin (usr jsonb_path_ops);

Related:

I achieve this by unnesting with jsonb_array_elements(). (unnest() is only good for Postgres arrays, not for JSON arrays.) And since we are only interested in actually matching objects I add a join condition right away.

Related:

  1. Extract the value for the key 'count'.

After qualifying objects have been extracted, this is simply: obj.value->>'count'.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.