2016-04-13 5 views
0

私は3つの実体をデータベースに持っています。ボード、リスト、カード。彼らは1対1の関係を持っています。ボードにはリストが含まれ、リストにはカードが含まれます。PostgreSQLでネストされたJSONを取得するためのクエリを簡略化する方法はありますか?

ボード:

CREATE TABLE boards(
    id serial PRIMARY KEY, 
    title text NOT NULL 
); 
CREATE TABLE boards_lists(
    board_id integer NOT NULL REFERENCES boards ON DELETE RESTRICT, 
    list_id integer PRIMARY KEY REFERENCES lists ON DELETE CASCADE 
); 

リスト:

CREATE TABLE lists(
    id serial PRIMARY KEY, 
    title text NOT NULL 
); 
CREATE TABLE lists_cards(
    list_id integer NOT NULL REFERENCES lists ON DELETE RESTRICT, 
    card_id integer PRIMARY KEY REFERENCES cards ON DELETE CASCADE 
); 

カード:例えば

CREATE TABLE cards(
    id serial PRIMARY KEY, 
    text text NOT NULL 
); 

、Iは2つのルートを持っている:

1. GET /ボードは - ボード、リストやカードで深いネストされたJSONを返す必要があります

[ 
{ 
    id: 1, 
    title: 'board 1', 
    lists: [ 
    { 
     id: 1, 
     title: 'list 1', 
     cards: [ 
     { 
      id: 1, 
      text: 'card 1' 
     } 
     ] 
    } 
    ] 
} 
] 

2. GET /リスト - 私は上記のように、ボードなしで、同じJSONを返す必要がありますカード付きリストのみ。

だから、DBの中にすべてのリストとカードを入れておく必要があります。私は、このクエリを使用します。

WITH full_lists AS (
    SELECT l.*, 
     COALESCE (json_agg(c) FILTER (WHERE c.id IS NOT NULL), '[]') AS cards 
    FROM lists AS l 
    LEFT JOIN lists_cards ON (l.id = list_id) 
    LEFT JOIN cards AS c ON (c.id = card_id) 
    GROUP BY l.id 
) 
SELECT b.*, 
    COALESCE (json_agg(l) FILTER (WHERE l.id IS NOT NULL), '[]') AS lists 
FROM boards AS b 
LEFT JOIN boards_lists ON (b.id = board_id) 
LEFT JOIN full_lists as l ON (l.id = list_id) 
GROUP BY b.id 

それは正常に動作しますが、私は、私はボードやリストを取得するための2つの類似SELECTクエリを持っているだけでなく、それは、非常に面倒だと思います。どのように私はそれを簡単にすることができますか?

+0

をなぜあなたがDBの側にそのロジックを実行する必要がありますか?あなたはフィルタリングをしません。すべてのデータをアプリに読み込んで処理できませんか? JSON(一般に生データよりも重い)を送信しないため、コード化/保守と効率化が容易になります。 – freakish

+0

このアクションはDB側で行う必要があると私は考えました。 3つのクエリを(各エンティティごとに)作成し、アプリケーションでデータをマージする方が簡単になるでしょうか? – 1ven

+0

まず第一に、あなたは何もしなくてはなりません。 :)しかし、はい、このアプローチは間違いなく簡単になり、拡張と維持が容易になります。より効率的かもしれませんが、これをベンチマークする必要があります。それは単なる提案です。 SQLを使って作業することは、ほとんどの場合アプリの側で難しく、IMHOはパフォーマンスが要求しない限り避けるべきです。 – freakish

答えて

関連する問題