こんにちは!スタジオウミの新田です。
最近とあるプロジェクトでViewsを使ったリスト(ビュー)を10個くらい作る機会がありました。Viewsは苦手だったのですが、いろいろと試行錯誤しているうちに、ちょっとしたコツで欲しいビューをさくっと取得できることに気づきました。というわけで今回はViewsを作るときに役立つ3つのコツを紹介したいと思います。
コツその1 目的とするクエリを先に考える
Viewsはクエリビルダーと呼ばれることからもわかるように、SQLクエリを作成して、その結果を表示するためのツールです。 新しいビューを作成するときは、どんなSQLクエリを作りたいか、そもそも一つのクエリで実行可能なのか、データベースを見てざっと確認しておきましょう。
コツその2 SQLクエリのプレビューをオンにする
一つ設定をするたびにViewsが実際にどんなSQLを発行しているか確認しながら作業を行うと効率がよくなります。以下の手順でビューズの設定からSQLクエリのプレビューをオンにしましょう。
- Views設定(
/admin/structure/views/settings
)に移動 - ライブプレビューの設定 > SQLクエリーを表示のチェックボックスをONにする
オンにすると画像のようにSQLクエリが表示されるようになります。
コツその3 SQLの句に対応するViewsの設定項目を意識する
SQLではデータベースのテーブル名やカラム名で欲しいデータを指定するのに対し、Viewsではエンティティタイプやフィールド名で指定するという違いはありますが、「フィールド = だいたいSELECT」、「フィルターの条件 = だいたいWHERE」のように、Viewsの設定はSQLの句に対応させることができます。これを意識することで設定画面でウロウロする時間を減らすことができます。
SQLとViewsの対応(画像)
SQLとViewsの対応(表)
Viewsの設定名 | 対応するSQLの句 | 説明 |
---|---|---|
ビューの種類 | FROM | 選択したエンティティタイプの代表的なテーブルがFROMで使われる。例: 「コンテンツ」を選択すると"FROM node_field_data"が追加される。 |
フィールド | SELECT | 選択したフィールドに紐づくカラムがSELECTに追加される。「ビューの種類」で読み込んだテーブル以外のテーブルが必要な場合は自動的にJOINが行われる。(同じエンティティタイプに紐づくテーブルのみ。他のエンティティタイプのテーブルを結合する場合はリレーションシップを組む必要がある) 例: 「コンテンツ」カテゴリーの「ID」を追加すると、"SELECT node_field_data.nid" が追加される。 |
フィルターの条件 | WHERE | 選択したフィールドに紐づくカラムがWHEREに追加される。 オペレーターや比較基準となる値は詳細設定から指定する。「現在のユーザー」、「現在閲覧しているノード」などのコンテクストが必要な場合はコンテクスチュアルフィルターを使う。 例: 「コンテンツ」カテゴリーの「ID」を選択し、「オペレータ」と「値」をそれぞれ「等しくない」、「10」と設定すると、"WHERE node_field_data.nid != '10' "が追加される。 |
並び替え基準 | ORDER BY | 選択したフィールドに紐づくカラムがORDER BYに追加される。降順、昇順は詳細設定から指定する。例: 「コンテンツ」カテゴリの「投稿日時」を選択し、「降順」に設定すると、"ORDER BY node_field_data_created DESC"が追加される。 |
コンテクスチュアルフィルター | WHERE | WHERE句が追加されるところは通常の絞り込みと同じだが、「現在のユーザー」、「現在閲覧しているノード」などのコンテクストを利用した絞り込みを行うことができる。 例: 「コンテンツ」カテゴリーの「ID」を選択し、「フィルター値が利用可能でない時」は「デフォルト値を使用」、「タイプ」を「URLから取得したコンテンツID」と設定し、プレビューの「コンテクスチュアルフィルターでプレビュー」に1と入力すると、"WHERE node_field_data.nid != 1" が追加される。 |
リレーションシップ | JOIN | 選択したリレーション(現在のエンティティタイプに対して他のエンティティタイプやフィールドを紐付けすること)に必要なテーブルがJOINされる。基本的にはLEFT JOINだが、「このリレーションシップを必須にする」にチェックを入れるとINNER JOINになる。 例: ビューの種類が「コンテンツ」の状態で「field_tagsから参照されているタクソノミーターム」というリレーションを追加すると、 まず"LEFT JOIN node__field_tags"が追加され、次に"LEFT JOIN taxonomy_term_field_data"が追加される。(ON句はエンティティIDなどでよしなにやってくれる。) |
アグリゲーションを使用 | GROUP BY | 有効化すると、GROUP BYが追加される。GROUP BY の後ろには現在選択中のフィールド全てが自動的に追加される。GROUP BYとよく同時に使われるMIN、MAX、COUNTなどはアグリゲーションを有効化すると各フィールドで設定できるようになる。例: 「コンテンツ」のビューで「タイトル」、「コンテンツタイプ」がフィールドとして選択されている状態で「アグリゲーションを使用(高度>その他)」の「集約」をONにする。タイトルとコンテンツタイプの「アグリゲーションの設定」でそれぞれ「カウント」「結果をグループにまとめる」を選ぶと、"GROUP BY node_field_data_type"が追加され 、"SELECT node_field_data.nid" は"SELECT OUNT(node_field_data.nid)"に修正される。 |
重複削除 | DISTINCT | 有効化すると、DISTINCTが追加される。「クエリーの設定(高度>その他)」の「重複削除」にチェックを入れると、"SELECT"が"SELECT DISTINCT"に修正され、全く同じ行は1件ずつしか表示されなくなる。 |
まとめ
とにかく、Viewsは背後にあるSQLをもとに考えると楽ちん、という話でした。今回紹介したコツを駆使すると、複数のJOINやGROUP BYがあるような複雑なクエリでも1、2時間くらいでさくっと作ることができるようになるので、試してみてくださいね。
募集しています
スタジオ・ウミは「Drupal」に特化したサービスを提供する Drupal のエキスパートチーム。
フルリモート&フレックス制だから、働く場所を選ばず時間の使い方も自由です。
そんなワークライフバランスの整った環境で、当ブログに書かれているような
様々な技術を共に学びながら、Drupalサイト開発に携わってみたい方を募集しています。
まずはお話だけでも大歓迎!ぜひお気軽にご連絡ください。