2

I am using postgres 9.5.4.

From below sample json data stored in jsonb column, I would like to search records matching o['mid'] > 7000

This is sample of one user's record. There will be millions of such users.

{
  "uid": 14105529,
  "o": [
    {
      "mid": 6551,
      "ac": 1913,
      "ip": "144.36.233.44",
      "adw": 5,
      "at": 133000,
      "ad": 151015,
      "aid": 0
    },
    {
      "mid": 7552,
      "ac": 1913,
      "ip": "144.36.233.44",
      "adw": 5,
      "at": 133000,
      "ad": 151015,
      "aid": 0
    },
    {
      "mid": 7553,
      "ac": 1913,
      "ip": "144.36.233.44",
      "adw": 5,
      "at": 133000,
      "ad": 151015,
      "aid": 0
    }
  ]
}

1 Answer 1

2
with a_table(jdata) as ( 
values (
    '{
        "uid":14105529,
        "o":[
            {"mid":6551,"ac":1913,"ip":"144.36.233.44","adw":5,"at":133000,"ad":151015,"aid":0}, 
            {"mid":7552,"ac":1913,"ip":"144.36.233.44","adw":5,"at":133000,"ad":151015,"aid":0},
            {"mid":7553,"ac":1913,"ip":"144.36.233.44","adw":5,"at":133000,"ad":151015,"aid":0} 
        ] }'::jsonb
    )
)

select jdata->'uid' as uid, value
from a_table, jsonb_array_elements(jdata->'o')
where (value->>'mid')::int > 7000;

   uid    |                                              value                                               
----------+--------------------------------------------------------------------------------------------------
 14105529 | {"ac": 1913, "ad": 151015, "at": 133000, "ip": "144.36.233.44", "adw": 5, "aid": 0, "mid": 7552}
 14105529 | {"ac": 1913, "ad": 151015, "at": 133000, "ip": "144.36.233.44", "adw": 5, "aid": 0, "mid": 7553}
(2 rows)

The query will be really expensive for a large dataset because of necessity of unnesting the json array with jsonb_array_elements(). There is no index you could use to speed it up.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks a lot Klin. This works for me. As you mentioned, need to check performance on large dataset.
@ klin, facing issue while executing this query on citus cluster. Need help. postgres=# select count(1) from jsontest, jsonb_array_elements(data->'o') where (value->>'mid')::int>7000; ERROR: cannot perform distributed planning on this query DETAIL: Complex table expressions are currently unsupported
Unfortunately, this is not a standard Postgres error message. It seems citus has additional limitations, see this citus issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.