0

I have a table uploads_table:

upload_id value
A [{"doc_name": "doc1a", "doc_type": "pdf"}, {"doc_name": "doc1b", "doc_type": "csv"}]
B [{"doc_name": "doc2a", "doc_type": "csv"}, {"doc_name": "doc2b", "doc_type": "csv"}]
C [{"doc_name": "doc3a", "doc_type": "pdf"}]

What would be the Postgres query to return all the upload_id, value from uploads_table which has at least one "doc_type" as "pdf".

Expected result:

upload_id value
A [{"doc_name": "doc1a", "doc_type": "pdf"}, {"doc_name": "doc1b", "doc_type": "csv"}]
C [{"doc_name": "doc3a", "doc_type": "pdf"}]
Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228
Kaushik J
  • 962
  • 7
  • 17

2 Answers2

4

Use the jsonb "contains" operator @>:

SELECT *
FROM   uploads_table
WHERE  value @> jsonb '[{"doc_type":"pdf"}]';

This is, of course, assuming that value is type jsonb - as it should be.

A GIN index on (value) will make this fast.
Even faster with a more specialized jsonb_path_ops index:

CREATE INDEX uploads_table_values_gin_idx ON uploads_table USING gin (value jsonb_path_ops);

See:

Related:

Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228
0

You can use the built-in function jsonb_array_elements in PostgreSQL. The query statement will be as follows:

SELECT *
FROM uploads_table
WHERE EXISTS (
    SELECT 1
    FROM jsonb_array_elements(value) AS doc
    WHERE doc->>'doc_type' = 'pdf'
);

The result is as shown in the image below: enter image description here

Frank Heikens
  • 117,544
  • 24
  • 142
  • 135
fixcer
  • 129
  • 1
  • 5