简体   繁体   中英

PostgreSQL filter based on an id in a nested json array

I have a json field (stored as text) in a table and I want to extract certain items from the json that have a specified ID in a nested array (within the json).

Each json item has a type attribute and a value attribute. The value furthermore has a GRI attribute (array) which I would like to use to filter. Here is a sample of one streamfield column item:

[{"type": "paragraph", 
    "value": {"paragraph": "<p>Sample paragraph 91</p>", "GRI": [27, 91, 211]},
 {"type": "paragraph", 
    "value": {"paragraph": "<p>Sample paragraph 191</p>", "GRI": [13, 191, 271]}]

This query sort of works:

SELECT value FROM "sampletable" r, json_array_elements(r.streamfield::json) obj 
WHERE  obj->>'type' = 'paragraph' AND obj#>>'{value,GRI}' LIKE '%91%';

This would give me all items with ID 91. But also with ID 191, 291 etc...

So how can I convert the `obj#>>'{value,GRI}' statement into an array so that I can filter based on the specified ID?

Here is an SQLFiddle for this: http://sqlfiddle.com/#!15/184e1/1

Edit: clarified structure of JSON

Here's how I would approach this. Basically, you need to return the items of the JSON array as a set, then create a PostgreSQL array from it.

DROP TABLE IF EXISTS "sampletable";
CREATE TEMP TABLE "sampletable" (streamfield TEXT);
INSERT INTO "sampletable" VALUES ('{"type": "paragraph", "value": {"paragraph": "<p>Sample paragraph 91</p>", "GRI": [27, 91, 211]}}');

-- Easier to separate out in a CTE, but this could be a subquery, if need be.
WITH cte AS
(
  SELECT
    (streamfield::JSON)->>'type' AS type_text,
    JSON_EXTRACT_PATH_TEXT(streamfield::JSON,'value','paragraph') AS paragraph_text,
    (SELECT ARRAY_AGG(col::INT) FROM JSON_ARRAY_ELEMENTS_TEXT(JSON_EXTRACT_PATH(streamfield::JSON,'value','GRI')) tbl(col)) AS gri_array -- This is an INT array now
  FROM
    "sampletable"
)

SELECT
  type_text,
  paragraph_text,
  gri_array
FROM
  cte
WHERE
  type_text = 'paragraph' AND
  91 = ANY(gri_array)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM