mcpField
L
lookml-liquid

lookml-liquid

github.com/looker-open-source数据与数据库43148 次安装2 周前更新
代码仓库

关于 lookml-liquid

这是一份 LookML Liquid 变量和标签的参考技能,面向需要在 Looker 模型中编写动态逻辑的人员。内容说明变量用途、条件判断、用户输入的 SQL 安全处理,以及查询字段状态对逻辑和性能的影响。

主要功能

  1. 01列出 Liquid 变量及适用位置
  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:数据库中的原始值(最适合用于比较)。
    • rendered_value:格式化后的值(最适合用于显示)。
    • _filters['view.field']:用户选择的筛选值。
    • parameter_name._parameter_value:选定的参数值。
  3. 最佳实践:
    • SQL 注入:将用户输入(如 _filters)插入生成字符串字面量的 SQL 时,始终使用 | 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_value为 URL 筛选格式化后的值。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如果查询了该视图中的任意字段,则为 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 %} ;;
  }
}

注: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 %}
  ;;
}

评论

支持 Markdown