Как "заархивировать" несколько вложенных массивов JSON без использования ключа id? - PullRequest
0 голосов
/ 21 февраля 2019

Я пытаюсь объединить несколько вложенных массивов JSON, не глядя на id.В настоящее время я получаю это, когда делаю GET запрос на /surveyresponses:

{
"surveys": [
    {
        "id": 1,
        "name": "survey 1",
        "isGuest": true,
        "house_id": 1
    },
    {
        "id": 2,
        "name": "survey 2",
        "isGuest": false,
        "house_id": 1
    },
    {
        "id": 3,
        "name": "survey 3",
        "isGuest": true,
        "house_id": 2
    }
],
"responses": [
    {
        "question": "what is this anyways?",
        "answer": "test 1"
    },
    {
        "question": "why?",
        "answer": "test 2"
    },
    {
        "question": "testy?",
        "answer": "test 3"
    }
]
}

Но я хотел бы получить его там, где у каждого опроса есть свой вопрос и ответы, вот так:

{
"surveys": [
    {
        "id": 1,
        "name": "survey 1",
        "isGuest": true,
        "house_id": 1
        "question": "what is this anyways?",
        "answer": "test 1"
    }
]
}

Потому что я не собираюсь на конкретный id Я не уверен, как заставить отношения работать.Это текущий запрос, который дает эти результаты.

export function getSurveyResponse(id: number): QueryBuilder {
return db('surveys')
    .join('questions', 'questions.survey_id', '=', 'surveys.id')
    .join('questionAnswers', 'questionAnswers.question_id', '=', 'questions.id')
    .select('surveys.name', 'questions.question', 'questions.question', 'questionAnswers.answer')
    .where({ survey_id: id, question_id: id })
}

1 Ответ

0 голосов
/ 21 февраля 2019

Предполагая jsonb в текущих Postgres 10 или 11 , этот запрос выполняет работу:

SELECT t.data, to_jsonb(s) AS new_data
FROM   t
LEFT   JOIN LATERAL (
   SELECT jsonb_agg(s || r) AS surveys
   FROM  (
      SELECT jsonb_array_elements(t.data->'surveys') s
           , jsonb_array_elements(t.data->'responses') r
      ) sub
   ) s ON true;

db <> fiddle here

Я разворачиваю оба вложенных массива JSON параллельно, чтобы получить желаемое поведение "архивирования" обоих напрямую.Количество элементов в обоих вложенных массивах JSON должно совпадать или вам нужно делать больше (иначе вы потеряете данные).

Это основано на деталях реализации того, как Postgres работает с несколькими функциями, возвращающими множество в SELECT список, чтобы сделать его коротким и быстрым.См .:

С * 1026 можно было бы сделать более явным* выражение, которое работает должным образом с Postgres 9.4 :

SELECT t.data
     , to_jsonb(s) AS new_data
FROM   tbl t
LEFT   JOIN LATERAL (
   SELECT jsonb_agg(s || r) AS surveys
   FROM   ROWS FROM (jsonb_array_elements(t.data->'surveys') 
                   , jsonb_array_elements(t.data->'responses')) sub(s,r)
   ) s ON true;

Руководство по объединению нескольких табличных функций.

Или вы можете использовать WITH ORDINALITY, чтобы получить оригинальный порядок элементов и объединить, как вы хотите:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...