Postgres jsonb, запрос вложенного массива, чтобы скрыть определенные поля

У меня есть данные jsonb следующего формата с вложенными массивами

{
  "outerArray": [
    {
      "price": {
        "amount": 108.95,
        "currencyCode": "GBP"
      },
      "innerArray": [
        {
          "details": {
            "field1": "val1",
            "field2": "val2",
            "field3": "val3"
          },
          "otherDetail": {
            "date": "2016-07-23",
            "time": "19:43:00"
          },
          "innerMostArray": [
            {
              "A1": "A1"
            },
            {
              "B1": "B1"
            }
          ]
        }
      ],
      "someField": "values"
    },
    {
      "price": {
        "amount": 108.95,
        "currencyCode": "GBP"
      },
      "innerArray": [
        {
          "details": {
            "field1": "val1",
            "field2": "val2",
            "field3": "val3"
          },
          "otherDetail": {
            "date": "2016-07-23",
            "time": "19:43:00"
          },
          "innerMostArray": [
            {
              "A1": "A1"
            },
            {
              "B1": "B1"
            }
          ]
        }
      ],
      "someField": "values"
    }
  ]
}

Я хочу написать запрос на получение этого, чтобы сохранить ту же структуру json, но скрыть поля «цена», «подробности», «otherDetail» и «someField»

Полученный результат должен выглядеть так

{
  "outerArray": [
    {
      "innerArray": [
        {
          "innerMostArray": [
            {
              "A1": "A1"
            },
            {
              "B1": "B1"
            }
          ]
        }
      ]
    },
    {
      "innerArray": [
        {
          "innerMostArray": [
            {
              "A1": "A1"
            },
            {
              "B1": "B1"
            }
          ]
        }
      ]
    }
  ]
}

Можно ли это сделать?


person phx    schedule 15.03.2017    source источник
comment
да, это можно было сделать. какой запрос у вас есть до сих пор?   -  person Vao Tsun    schedule 15.03.2017
comment
Я новичок в jsonb и postgres. В моем реальном сценарии было несколько других вложений, и для достижения этого текущего json я использовал файл jsonb_extract_path_text. И в настоящее время я извлекаю все данные json из postgress и делаю часть скрытия/отображения со своей стороны, используя jackson json.   -  person phx    schedule 15.03.2017
comment
в зависимости от версии Postres, которую вы используете, это более или менее удобно делать, но это только мое мнение манипулировать json с помощью js всегда удобнее   -  person Vao Tsun    schedule 15.03.2017
comment
Я использую 9.4.7   -  person phx    schedule 16.03.2017


Ответы (1)


Пожалуйста, всегда указывайте версию PostgreSQL, которую вы используете. Пример ниже должен нормально работать для версий v9.5+.

Я бы подошел к этому, создав объект JSONB, который вам нужен, с jsonb_build_object() и jsonb_build_array() функции:

Пример запроса:

WITH test(data) AS ( VALUES
  ('{
      "outerArray": [
        {
          "price": {
            "amount": 108.95,
            "currencyCode": "GBP"
          },
          "innerArray": [
            {
              "details": {
                "field1": "val1",
                "field2": "val2",
                "field3": "val3"
              },
              "otherDetail": {
                "date": "2016-07-23",
                "time": "19:43:00"
              },
              "innerMostArray": [
                {
                  "A1": "A1"
                },
                {
                  "B1": "B1"
                }
              ]
            }
        ],
        "someField": "values"
      },
    {
      "price": {
        "amount": 108.95,
        "currencyCode": "GBP"
      },
      "innerArray": [
        {
          "details": {
            "field1": "val1",
            "field2": "val2",
            "field3": "val3"
          },
          "otherDetail": {
            "date": "2016-07-23",
            "time": "19:43:00"
          },
          "innerMostArray": [
            {
              "A1": "A1"
            },
            {
              "B1": "B1"
            }
          ]
        }
      ],
      "someField": "values"
    }
  ]}'::JSONB)
)
SELECT
  jsonb_build_object(
    'outerArray',
    array_agg(
        jsonb_build_object(
            'innerArray',
            json_build_array(
                json_build_object(
                    'innerMostArray',
                    innerArray->'innerMostArray')
            )
        )
    )
  ) as result
FROM test t,
    jsonb_array_elements(t.data->'outerArray') as outerElement,
    jsonb_array_elements(outerElement->'innerArray') as innerArray;

Результат:

    result                                                                          
----------------------------------------------------------------------------------------------------------------------------------------------------------
 {"outerArray": [{"innerArray": [{"innerMostArray": [{"A1": "A1"}, {"B1": "B1"}]}]}, {"innerArray": [{"innerMostArray": [{"A1": "A1"}, {"B1": "B1"}]}]}]}
(1 row)
person Dmitry Savinkov    schedule 15.03.2017
comment
Извините, что не указал версию. Я использую 9.4.7. - person phx; 16.03.2017