mcpField
L
lookml-liquid

lookml-liquid

github.com/looker-open-sourceデータ・データベース43148 回インストール2 週間前に更新
リポジトリ

lookml-liquid について

Lookerモデルで動的ロジックを書く人向けの、LookML Liquid変数とタグのリファレンススキルです。変数の用途、条件分岐、ユーザー入力のSQLでの安全な扱い、クエリー内のフィールド状態がロジックや性能に与える影響を説明します。

主な機能

  1. 01Liquid変数と使用箇所を一覧化
  2. 02_in_queryと_is_selectedを比較
  3. 03ユーザー入力のSQLクォートを解説
  4. 04動的なテーブル選択と結合を提示
  5. 05フィールド参照の性能への影響を説明

活用シーン

  1. 01クエリー内のフィールドに応じてテーブルを選択
  2. 02フィルター値からSQL条件を生成
  3. 03選択フィールドに応じて計算を変更
  4. 04リンクフィールドによる余分なグループ化を回避

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/looker-open-source/looker-skills --skill lookml-liquid

インストール後、Claude Code で/lookml-liquidを入力して読み込まれたか確認します。

詳細

手順

  1. 構文:
    • {{ value }}:出力構文(テキストを挿入します)。
    • {% if condition %}:タグ構文(ロジックを記述します)。
  2. 一般的な変数:
    • value:DB の生の値(比較に適しています)。
    • rendered_value:書式設定済みの値(表示に適しています)。
    • _filters['view.field']:ユーザーが選択したフィルター値。
    • parameter_name._parameter_value:選択されたパラメーター値。
  3. ベストプラクティス:
    • SQL インジェクション:SQL の文字列リテラルを生成する際、ユーザー入力(_filters など)を挿入する場合は、必ず | sql_quote を使用してください。
    • ブール値:方言でリテラルの TRUE/FALSE が必要な場合(BigQuery など)は、_in_query または _is_selected 変数に | sql_boolean を付けてください(例:{{ view.field._in_query | sql_boolean }})。
    • 依存関係の把握:_in_query は、SELECT、フィルター、required_fields での使用を確認します。表示列だけが対象ではありません。
    • パフォーマンス:フィールドがすでにクエリに含まれていない場合は、link パラメーター内で {{ field._value }} を参照しないでください。Looker によってフィールドが GROUP BY 句に追加され、結果セットがファンアウトする可能性があります。ブラウザーの結果行から値を取得するだけであれば、代わりに row['view.field'] を使用してください。

高度な変数の使い方

_in_query と _is_selected の違い

変数定義重要な違い(合計)
_in_queryフィールドが SELECT 句、フィルター、または required_fields に含まれている場合、true を返します。フィールドがクエリに寄与していた場合、合計の計算中も true のままです。
_is_selectedフィールドが SELECT 句または required_fields に含まれている場合、true を返します。ディメンションは合計の計算のためにクエリから除外されるため、合計の計算中(行/列/総合計)は false を返します。

警告

ディメンションのロジックを条件付きでレンダリングするために _is_selected を使用すると、合計行ではそのロジックが 機能しません(false を返します)。合計でもロジックを維持する必要がある場合は _in_query を使用するか、合計での動作として意図するのであれば、false の状態を明示的に処理してください。

Liquid 変数の定義

次の表では、LookML で使用できる Liquid 変数とその使用箇所について説明します。

使用箇所のキー:

  • A:action
  • DV:default_value(ダッシュボード)
  • DE:description
  • F:filters(ダッシュボード要素)
  • H:html
  • LA:ラベルパラメータ(label、view_label、group_label、group_item_label)
  • LI:link
  • S:SQL パラメータ(sql、sql_on、sql_table_name)
変数定義使用箇所
valueフィールドの未加工の値です。A, H, LI
rendered_valueフィールドの書式設定済みの値です。A, H, LI
filterable_valueURL フィルタリング用に書式設定された値です。A, H, LI
linkデフォルトのドリルリンク URL です。A, H, LI, S
linked_valueデフォルトの書式設定とリンクが適用された値です。A, H, LI
_filters['view.field']フィールドに適用されたユーザーフィルタです。A, DE, H, LA, LI
{% date_start filter %}日付フィルタの開始日です。S
{% date_end filter %}日付フィルタの終了日です。S
{% condition filter %} sql {% endcondition %}SQL にフィルタロジックを適用します。S
{% parameter name %}パラメータの値です。DE, LA, S
name._parameter_valueパラメータの値を挿入します(ロジックに安全に使用できます)。DE, H, LA, LI, S
_user_attributes['name']ユーザー属性の値です。A, DE, H, LA, LI, S, DV, F
_model._nameモデル名です。A, DE, H, LA, LI, S
_view._nameビュー名です。A, DE, H, LA, LI, S
_explore._nameExplore 名です。A, DE, H, LA, LI, S
_field._nameフィールド名です。A, DE, H, LA, LI, S
view._in_queryビューのフィールドが 1 つでも クエリされている場合は true です。DE, LA, LI, S
view.field._in_queryフィールドがクエリまたはフィルタに含まれている場合は true です。DE, LA, LI, S
view.field._is_selectedフィールドが SELECT に含まれている場合は true です。DE, LA, LI, S
view.field._is_filteredフィールドがフィルタされている場合は true です。DE, LA, LI, S

高度なユースケース

1. 集計認識(動的なテーブル選択)

ユーザーが詳細なデータを要求していない場合に、_in_query を使ってクエリをより小さな事前集計テーブルに振り分けます。これにより、クエリのパフォーマンスが大幅に向上します。

view: orders {
  sql_table_name:
    {% if orders.created_date._in_query or orders.created_hour._in_query %}
      orders_daily_summary  -- Fallback to daily partition if granular date used
    {% elsif orders.created_month._in_query %}
      orders_monthly_summary -- Use monthly summary for high-level queries
    {% else %}
      orders_all_transactions -- Default/Detail table
    {% endif %} ;;
}

2. 動的な結合(sql_on)

結合で _in_query を使うと、ユーザーが選択した項目に実際に必要な場合を除き、負荷の高いテーブルの結合を避けられます。

explore: order_items {
  join: users {
    type: left_outer
    sql_on: ${order_items.user_id} = ${users.id} ;;
    relationship: many_to_one
  }

  join: user_facts {
    type: left_outer
    sql_on: ${users.id} = ${user_facts.user_id} ;;
    relationship: one_to_one
    # Only join user_facts if a field from it is actually selected/filtered
    sql_where: {% if user_facts._in_query %} 1=1 {% else %} 1=0 {% endif %} ;;
  }
}

注:一部の方言では、結合を解除させる方法の 1 つとして sql_where の手法がありますが、サポートされている場合は、{% if %} を使った標準的な sql_on ロジックのほうがすっきりします。

3. 列固有のロジック(動的な分母)

クエリにほかのフィールドが含まれているかどうかに応じて、計算を変更します。

measure: dynamic_rate {
  type: number
  sql:
    {% if users.traffic_source._is_selected %}
      ${total_revenue} / NULLIF(${traffic_source_count}, 0)
    {% else %}
      ${total_revenue} / NULLIF(${total_users}, 0)
    {% endif %} ;;
}

例

動的 HTML(条件付き書式設定)

dimension: status {
  html:
    {% if value == 'complete' %}
      <span style="color: green">{{ rendered_value }}</span>
    {% else %}
      <span style="color: red">{{ rendered_value }}</span>
    {% endif %} ;;
}

テンプレート化されたフィルタ(派生テーブル)

view: customer_facts {
  derived_table: {
    sql:
      SELECT customer_id, SUM(amount)
      FROM orders
      WHERE {% condition order_date %} created_at {% endcondition %}
      GROUP BY 1 ;;
  }
}

複雑なロジック(ループと分割)

LookML の Liquid は文字列操作やループを処理できるため、複雑なフィルタパラメータの解析や値のアンネストに役立ちます。使用頻度は低いものの、複雑なモデリングタスクでは非常に便利です。

view: brand_category_item {
  parameter: filter { type: unquoted }
}

explore: complex_filter_parsing {
  # Example: Parsing a string like "Brand1..Category1__Brand2..Category2"
  # This logic splits the string by '__' then '..' to generate OR conditions
  sql_where:
    {% assign items = brand_category_item.filter._parameter_value | split: '__' %}
    {% for item in items %}
      {% assign parts = item | split: '..' %}
      {% if forloop.first %} ( {% else %} OR ( {% endif %}
        ${products.brand} = '{{ parts[0] }}' AND ${products.category} = '{{ parts[1] }}'
      )
    {% endfor %}
    {% if items.size == 0 %} 1=1 {% endif %}
  ;;
}

コメント