LookerのSubstitution Syntaxを使いこなして繰り返し作業を無くす
大阪オフィスの玉井です。
LookerでLookMLを書いたり人のを見たりしていると、結構出てくるドルマークで始まる構文。これ、何か知ってますか?
これはSubstitution Syntax(置換構文)といって、他のビュー等で書かれた項目を参照できるものです。要するに、一度LookMLで定義されたものを、別の部分でも使いたい時は、この構文を使ってお手軽に再利用できるということです。これはLookerが促進しているDRY原則(Don’t Repeat Yourself)に基づく機能の1つとなっています。
ドルマークが基本
$
←こいつをLookMLの世界では「Substitution Operator」と呼称します。これから始まる構文が置換構文になる…というわけですね。使い方にいくつかのパターンがあるので紹介します。
色々な使用パターン
${TABLE}
一番よく見る書き方としてはこれでしょうか。
dimension: category { type: string sql: ${TABLE}."Category" ;; }
これは、そのviewファイル上で定義されているテーブルを指します。viewファイルは(基本的には)接続しているDBの1テーブルに対応しており、viewファイルの一番上に「このviewファイルは○○っていう名前のテーブルと対応しているよ」的なことが記述されています。
view: order { sql_table_name: public."order" ;; drill_fields: [order_id]
上記でいえば「このviewファイルはpublicスキーマのorderテーブルを使う」と定義しています。ですので…
view: order { sql_table_name: public."order" ;; drill_fields: [order_id] dimension: category { type: string sql: ${TABLE}."Category" ;; } ...
上記の場合、${TABLE}
はsql_table_name
の値を参照します(つまりpublic."order"
)。
項目毎にいちいちテーブル名を記述する必要が無いのも良い点ですが、一番のメリットは、テーブル名が変わったとしても、一番上の記述だけ変更すれば済むという点です。
${<フィールド名>}
これもシンプルです。同一viewファイル内で既に定義されているdimensionやmeasureを参照します。
例えば下記のように記述します。
dimension: category { type: string sql: ${TABLE}."Category" ;; } dimension: カテゴリー { type: string sql: ${category} ;; }
下記のカテゴリー
は上記のcategory
を参照しています。つまり、カテゴリー
を使用しても実質的にはcategory
を使うのと変わりません。
生成されたクエリを見ると、ちゃんと置換されているのがわかります。
${<ビュー名>.<フィールド名>}
既に定義されているdimensionやmeasureを参照するという点では上記と同じですが、それが別のviewファイルにある場合は、こちらの書き方を使います。
view: order_sequence { dimension: category { type: string sql: ${order.category} ;; } ... }
上記はorder_sequence
というviewファイルですが、dimensionのcategory
は、別のviewファイルであるorder
のcategory
というdimensionを参照しています。
${<ビュー名>.SQL_TABLE_NAME}
今までのやつよりもちょっと特殊です。特殊といっても、この構文自体の意味は、単純に別のviewファイル(または派生テーブル)で使用されているテーブル名を参照する…というシンプルなものです。ただ、使いどころがちょっと違う感じがあります(個人的な感想)。
これは自分で例が思いつかなかったので、公式ドキュメント(本エントリ下部にリンクを貼っています)から引用します。
explore: trips { view_label: "Long Trips" # This will ensure that we only see trips that are longer than average! sql_always_where: ${trips.trip_duration}>=(SELECT tripduration FROM ${average_trip_duration.SQL_TABLE_NAME});; }
trips
という名前のexploreを定義しています。そこにsql_always_where
というパラメータが書かれています。このパラメーターは、そこに書かれているWHERE句を、そのexploreを使用する時に必ず実行させるようにするものです。
この例では、(コメントを読む限り)「旅行時間が平均より長いデータだけ出力する」ようにしています。もう少しカタい表現にすると、「trips
というviewファイルのtrip_duration
が、average_trip_duration
というviewファイルに定義されているテーブルのtripduration
というカラムの値以上のデータだけ」に絞っています。
その「average_trip_duration
というviewファイルに定義されているテーブル」という部分で、${<ビュー名>.SQL_TABLE_NAME}
の構文が使用されています。
これも、テーブル名直書きだった場合、テーブル名が変更された時のLookMLの修正が面倒なことになります。ですので、置換構文を使って、average_trip_duration
だけ修正すれば良いようにしています。
おわりに
LookerがDRY原則を徹底している(ユーザーに徹底させる)ことがわかる機能の1つでした(DRY原則の本質は繰り返しを無くすことそのものではなく、もっと壮大なものらしいんですけど、今回は触れません)。