lookml-liquid
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseInstructions
使用说明
- Syntax:
- : Output syntax (inserts text).
{{ value }} - : Tag syntax (logic).
{% if condition %}
- Common Variables:
- : Raw value from DB (best for comparisons).
value - : Formatted value (best for display).
rendered_value - : User-selected filter values.
_filters['view.field'] - : Selected parameter value.
parameter_name._parameter_value
- Best Practices:
- SQL Injection: Always use when inserting user input (like
| sql_quote) into SQL that generates string literals._filters - Booleans: If your dialect requires literal /
TRUE(like BigQuery), appendFALSEto| sql_booleanor_in_queryvariables (e.g.,_is_selected).{{ view.field._in_query | sql_boolean }} - Dependency Awareness: Remember that checks for usage in SELECT, Filters, and
_in_query. It is NOT limited to just the visible columns.required_fields - Performance: Avoid referencing in
{{ field._value }}parameters if the field isn't already in the query, as this forces Looker to add the field to thelinkclause, potentially fan-outing the result set. UseGROUP BYinstead if you only need the value from the browser result row.row['view.field']
- SQL Injection: Always use
- 语法:
- : 输出语法(插入文本)。
{{ value }} - : 标签语法(用于逻辑判断)。
{% if condition %}
- 常用变量:
- : 数据库中的原始值(最适合用于比较)。
value - : 格式化后的值(最适合用于展示)。
rendered_value - : 用户选择的筛选器值。
_filters['view.field'] - : 选中的参数值。
parameter_name._parameter_value
- 最佳实践:
- SQL注入防护: 当将用户输入(如)插入生成字符串字面量的SQL时,务必使用
_filters。| sql_quote - 布尔值处理: 如果你的SQL方言要求使用字面量/
TRUE(如BigQuery),请在FALSE或_in_query变量后追加_is_selected(例如:| sql_boolean)。{{ view.field._in_query | sql_boolean }} - 依赖关系认知: 请注意,会检查字段是否在**SELECT语句、筛选器及
_in_query**中被使用,并不局限于可见列。required_fields - 性能优化: 如果字段未包含在查询中,请避免在参数中引用
link,因为这会强制Looker将该字段添加到{{ field._value }}子句中,可能导致结果集膨胀。如果仅需浏览器结果行中的值,请改用GROUP BY。row['view.field']
- SQL注入防护: 当将用户输入(如
Advanced Variable Usage
高级变量用法
_in_query
vs _is_selected
_in_query_is_selected_in_query
与 _is_selected
对比
_in_query_is_selected| Variable | Definition | Critical Difference (Totals) |
|---|---|---|
| Returns | Remains |
| Returns | Returns |
[!WARNING] If you useto conditionally render logic for a dimension, that logic will fail (return false) in the Totals row. Use_is_selectedif you need the logic to persist in totals, or explicitly handle the_in_querystate for totals if that is the desired behavior.false
| 变量 | 定义 | 总计计算时的关键差异 |
|---|---|---|
| 如果字段存在于SELECT子句、筛选器或 | 如果字段为查询做出了贡献,在总计计算期间仍返回 |
| 如果字段存在于SELECT子句或 | 对于维度,在总计计算(行/列/总计行)期间返回 |
[!WARNING] 如果你使用为维度实现条件渲染逻辑,该逻辑在总计行中会失效(返回false)。如果需要逻辑在总计中保持生效,请使用_is_selected;如果希望总计行呈现false状态,请显式处理该情况。_in_query
Liquid Variable Definitions
Liquid变量定义
The following table describes the Liquid variables that you can use with LookML and where they can be used.
Usage Key:
- A:
action - DV: (dashboards)
default_value - DE:
description - F: (dashboard elements)
filters - H:
html - LA: Label parameters (,
label,view_label,group_label)group_item_label - LI:
link - S: SQL parameters (,
sql,sql_on)sql_table_name
| Variable | Definition | Usage |
|---|---|---|
| The raw value of the field. | A, H, LI |
| The formatted value of the field. | A, H, LI |
| The value formatted for URL filtering. | A, H, LI |
| The default drill link URL. | A, H, LI, S |
| The value with default formatting and linking. | A, H, LI |
| User filters applied to the field. | A, DE, H, LA, LI |
| Start date of a date filter. | S |
| End date of a date filter. | S |
| Applies filter logic to SQL. | S |
| Value of a parameter. | DE, LA, S |
| Injects parameter value (safe for logic). | DE, H, LA, LI, S |
| User attribute value. | 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 name. | A, DE, H, LA, LI, S |
| Field name. | A, DE, H, LA, LI, S |
| | DE, LA, LI, S |
| | DE, LA, LI, S |
| | DE, LA, LI, S |
| | DE, LA, LI, S |
下表描述了可在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
| 变量 | 定义 | 适用场景 |
|---|---|---|
| 字段的原始值。 | A, H, LI |
| 字段的格式化后的值。 | A, H, LI |
| 为URL筛选格式化后的值。 | A, H, LI |
| 默认钻取链接URL。 | A, H, LI, S |
| 带有默认格式与链接的值。 | A, H, LI |
| 应用于该字段的用户筛选器。 | A, DE, H, LA, LI |
| 日期筛选器的起始日期。 | S |
| 日期筛选器的结束日期。 | S |
| 为SQL应用筛选逻辑。 | S |
| 参数的值。 | DE, LA, S |
| 注入参数值(可安全用于逻辑判断)。 | DE, H, LA, LI, S |
| 用户属性值。 | A, DE, H, LA, LI, S, DV, F |
| 模型名称。 | A, DE, H, LA, LI, S |
| 视图名称。 | A, DE, H, LA, LI, S |
| Explore名称。 | A, DE, H, LA, LI, S |
| 字段名称。 | A, DE, H, LA, LI, S |
| 如果视图中的任意字段被查询,则返回 | DE, LA, LI, S |
| 如果字段存在于查询/筛选器中,则返回 | DE, LA, LI, S |
| 如果字段存在于SELECT子句中,则返回 | DE, LA, LI, S |
| 如果字段被筛选,则返回 | DE, LA, LI, S |
Advanced Use Cases
高级使用场景
1. Aggregate Awareness (Dynamic Table Selection)
1. 聚合感知(动态表选择)
Use to route queries to smaller, pre-aggregated tables when the user doesn't request granular details. This significantly improves query performance.
_in_querylookml
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 %} ;;
}当用户不需要粒度细节时,使用将查询路由到更小的预聚合表,这能显著提升查询性能。
_in_querylookml
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. Dynamic Joins (sql_on
)
sql_on2. 动态关联(sql_on
)
sql_onUse in joins to avoid joining heavy tables unless they are actually required by the user's selection.
_in_querylookml
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 %} ;;
}
}Note: The trick is one way to force a join drop in some dialects, but standard logic with is cleaner if supported.
sql_wheresql_on{% if %}在关联中使用,避免关联大表,除非用户的选择确实需要该表。
_in_querylookml
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方言中,技巧是强制取消关联的一种方式,但如果支持的话,使用带的标准逻辑会更简洁。
sql_where{% if %}sql_on3. Column-Specific Logic (Dynamic Denominator)
3. 列专属逻辑(动态分母)
Change a calculation based on what other fields are present in the query.
lookml
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 %} ;;
}根据查询中包含的其他字段更改计算方式。
lookml
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 %} ;;
}Examples
示例
Dynamic HTML (Conditional Formatting)
动态HTML(条件格式化)
lookml
dimension: status {
html:
{% if value == 'complete' %}
<span style="color: green">{{ rendered_value }}</span>
{% else %}
<span style="color: red">{{ rendered_value }}</span>
{% endif %} ;;
}lookml
dimension: status {
html:
{% if value == 'complete' %}
<span style="color: green">{{ rendered_value }}</span>
{% else %}
<span style="color: red">{{ rendered_value }}</span>
{% endif %} ;;
}Templated Filters (Derived Table)
模板化筛选器(派生表)
lookml
view: customer_facts {
derived_table: {
sql:
SELECT customer_id, SUM(amount)
FROM orders
WHERE {% condition order_date %} created_at {% endcondition %}
GROUP BY 1 ;;
}
}lookml
view: customer_facts {
derived_table: {
sql:
SELECT customer_id, SUM(amount)
FROM orders
WHERE {% condition order_date %} created_at {% endcondition %}
GROUP BY 1 ;;
}
}Complex Logic (Loops & Split)
复杂逻辑(循环与拆分)
LookML Liquid can handle string manipulation and loops, which is useful for parsing complex filter parameters or unnesting values. This is used infrequently, but very handy in complex modeling tasks.
lookml
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 %}
;;
}LookML Liquid支持字符串处理与循环,这在解析复杂筛选参数或展开值时非常有用。虽然使用频率不高,但在复杂建模任务中十分实用。
lookml
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 %}
;;
}