LookML 优化

概览

借助 LookML 细化,您可以调整现有的视图探索,而无需修改包含它们的 LookML 文件。此功能非常适合以下情况:

例如,如果您的项目中有以下视图文件:

view: flights {
  sql_table_name: flightstats.accidents ;;

  dimension: id {
    label: "id"
    primary_key: yes
    type: number
    sql: ${TABLE}.id ;;
  }
}

您可以按以下示例所示优化 flights 视图:使用 view 参数并指定相同的视图名称,但在名称前面添加加号 (+),以表明这是对现有视图的优化。

此细化操作会向现有 flights 视图添加 air_carrier 维度:

view: +flights {
  dimension: air_carrier {
    type: string
    sql: ${TABLE}.air_carrier ;;
  }
 }

此细化可以放在项目中的任何 LookML 文件中,例如模型文件、视图文件或其自己的专用 LookML 文件中。如需了解其运作方式,请参阅在 LookML 项目中使用细化部分。

细化与原始 LookML 相结合,最终结果就像是视图的原始 LookML:

view: flights {
  sql_table_name: flightstats.accidents ;;

  dimension: id {
    label: "id"
    primary_key: yes
    type: number
    sql: ${TABLE}.id ;;
  }

  dimension: air_carrier {
    type: string
    sql: ${TABLE}.air_carrier ;;
  }
}

在 Looker 界面中,用户将看到“航空公司”维度,就像您已将该维度添加到原始视图文件本身一样。

如需了解更详细的实现信息,请参阅示例部分。

与扩展相比,细化

Looker 还支持扩展 LookML 对象。如果您想创建现有视图或探索的新副本,以便向其中添加新对象,那么扩展功能非常有用。例如,您可以创建一个定义所有字段的基础视图,然后创建多个扩展基础视图的新视图。然后,您可以修改这些新视图,以隐藏基本视图中的某些字段,或更改基本视图中字段的定义或标签。

如果您想通过对某些对象进行细微调整来修改现有视图或探索,但不想创建视图或探索的副本,那么细化功能非常有用。在以下情况下,细化功能非常有用:您无法或不想修改基本视图或探索;创建新视图或探索需要对其他 LookML 引用进行大量更改。如需查看此使用场景的示例,请参阅本页上的示例部分。

对于大多数使用场景,细化是一种比 extends 更简单、更清晰的替代方案。

高级 LookML 开发者可能需要在 LookML 细化中使用 extends 参数。如需了解详情,请参阅本页的细化可包含扩展部分。

优化会替换大多数参数

请务必注意,在大多数情况下,优化会覆盖对象的原始设置。在以下示例中,原始视图具有隐藏维度 (hidden: yes):

view: faa_flights {
  dimension: carrier {
    hidden: yes
  }
}

在另一个文件中,使用 hidden: no 对该维度进行了细化:


include: "/views/faa_flights.view.lkml"

view: +faa_flights {
  dimension: carrier {
    hidden: no
  }
}

最后的细化优先,因此系统会应用 hidden: no,并且维度会显示在最终视图中。

在某些情况下,细化是累加的,而不是覆盖;如需了解详情,请参阅本页面的部分参数是累加的部分。

部分形参是累加的

在许多情况下,如果优化包含与要优化的对象相同的参数,则优化会替换优化对象的参数值

但对于某些参数,细化可以是累加的,这意味着基本对象中的值会与细化对象中的值结合使用。

以下参数是累加的:

例如,以下视图包含一个具有 link 参数的 name 维度:

view: carriers {
  sql_table_name: flightstats.carriers ;;

  dimension: name {
    sql: ${TABLE}.name ;;
    type: string
    link: {
      label: "Google {{ value }}"
      url: "http://www.google.com/search?q={{ value }}"
      icon_url: "http://google.com/favicon.ico"
    }
  }
}

下面是 carriers 视图的细化版本,其中包含一个 name 维度,该维度针对 link 参数具有不同的值:


include: "/views/carriers.view.lkml"

view: +carriers {
  label: "Refined carriers"

  dimension: name {
    sql: ${TABLE}.name ;;
    type: string
    link: {
      label: "Dashboard for {{ value }}"
      url: "https://docsexamples.dev.looker.com/dashboards/307?Carrier={{ value }}"
      icon_url: "https://www.looker.com/favicon.ico"
    }
  }
}

在优化后的 carriers 视图中,两个 link 参数是相加的,因此 name 维度将显示这两个链接。

优化按顺序应用

一个对象可以在多个位置多次进行细化,这让 Looker 开发者能够以多种创意方式使用细化。但这同时也意味着,开发者必须非常注意应用细化的顺序:

  • 在项目中,细化按其文件的包含顺序应用。最后包含的文件中的优化设置会覆盖之前包含的文件中的优化设置。
  • 在单个文件中,细化操作会逐行向下应用。行号最高的优化设置最后应用,如果存在冲突,则会覆盖任何之前的优化设置。

例如,在以下视图文件中,faa_flights 视图有两个细化版本。第一个优化会隐藏一个维度 (hidden: yes),而第二个优化会显示该维度 (hidden: no)。如果出现此类冲突,文件中最下面的优化会优先执行:

include: "//e_faa_original/views/faa_flights.view.lkml"

view: +faa_flights {
  dimension: carrier {
    hidden: yes
  }
}

view: +faa_flights {
  dimension: carrier {
    hidden: no
  }
}

在项目中包含多个文件时,逻辑类似:在 include 中列出的最后一个文件中的细化设置将具有优先权。例如,如果某个模型文件包含以下文件:

include: "/refinements/distance_analysis.lkml"
include: "/refinements/finishing_touches.lkml"

系统会先应用 distance_analysis.lkml 中的所有优化,然后再应用 finishing_touches.lkml 文件中的所有优化。如果存在任何冲突,则以最后一个文件 finishing_touches.lkml 中的细化为准。

使用 final: yes 阻止进一步细化

如前所述,同一对象可以在多个位置多次细化,最后一次细化覆盖之前的所有细化。

如果您希望某个优化被视为视图或探索的最终优化,可以向该优化添加 final: yes 标志。如果存在会在最终优化后应用的现有优化,或者开发者尝试添加会在最终优化后应用的新优化,Looker IDE 将返回 LookML 错误。例如,此视图文件中的第二个优化会产生 LookML 错误,因为上一个优化具有 final: yes 标志:

include: "//e_faa_original/views/faa_flights.view.lkml"

view: +faa_flights {
  final: yes
  dimension: carrier {
    hidden: yes
  }
}

view: +faa_flights {
  dimension: carrier {
    hidden: no
  }
}

向优化添加 final: yes 标志是验证优化是否按预期顺序应用的好方法。

细化可以包含扩展

高级 LookML 开发者可能希望在 LookML 细化中使用 extends 参数,该参数会将扩展对象添加到正在细化的对象中。

extends 和细化的行为总结如下:

  • 扩展对象会创建该对象的新副本,然后在此基础上进行构建。例如,您可以创建一个定义所有字段的基础视图,然后创建多个扩展基础视图的新视图。每个新视图都将包含基本视图的副本,然后开发者可以添加不同的字段、过滤条件或其他属性来修改基本视图中的内容。这种方法的思路是,先创建一个基本对象,然后在多个其他对象中以不同方式使用该对象。(如需全面了解如何使用 extends,请参阅通过 extends 重用代码文档页面。)
  • 优化对象会为对象添加一层修改,但与扩展不同,优化不会创建对象的多个副本。这种方法的目的是在不修改基础对象的原始 LookML 的情况下,以该对象为基础进行构建。

下面是一个细化标准用法的示例,其中包含一个名为 orders 的探索和一个细化该探索的 +orders 探索:

explore: orders {
  view_name: orders
  # other Explore parameters
}

explore: +orders {
  label: "Orders Information"
  # other Explore parameters to build on the original Explore
}

除此之外,您还可以添加包含 extends 的精细化调整。在上述示例的基础上,以下是相同的 orders 探索。此外,还有一个名为 users_base 的基础探索,现在 +orders 细化有一个 extends 参数,用于引入 users_base


explore: users_base {
  view_name: users
  extension: required
  # other Explore parameters
}

explore: orders {
  view_name: orders
  # other Explore parameters
}

explore: +orders {
  label: "Orders Information"
  extends: [users_base]
  # other Explore parameters to build on the original Explore
}

这里的特殊之处在于,+orders 细化包含 extends。这样一来,+orders 视图现在将扩展到 users_base“探索”视图。

Looker 如何在细化中实现 extends

扩展细化中的对象是一项高级 LookML 概念。在优化中使用 extends 之前,您应深入了解以下内容:

  • Looker 如何实现 extends:如果 LookML 元素同时在被扩展对象和扩展对象中定义,则使用扩展对象中的版本,除非相应参数是加法如需了解详情,请参阅通过 extends 重用代码文档页面。
  • Looker 如何实现细化:如果 LookML 元素在多个细化中定义,则最后一个细化会替换之前的细化。如需了解详情,请参阅本页中的细化按顺序应用部分。

最后,您应该了解 Looker 如何结合使用这些原则来实现细化中使用的 extends。以下是 Looker 的实现顺序,如果出现冲突,每个步骤都会覆盖上一个步骤:

  1. 对象中指定的 extends 的值
  2. 来自对象细化设置中指定的 extends 的值
  3. 对象中的值
  4. 对象细化的值

为了便于说明,以下示例展示了 label 参数在实现过程中的每个步骤中的值:

explore: orders_base {
  label: "Orders Base"
  view_name: orders
  extension: required
}

explore: users_base {
  label: "Users Base"
  view_name: users
  extension: required
}

explore: orders {
  label: "Orders"
  extends: [orders_base]
}

explore: +orders {
  label: "Orders Refined"
  extends: [users_base]
}

在此示例中,Looker 如何针对 orders 探索实现 label 的值:

  1. 对象中指定的 extends 中的值。由于 orders 探索具有 extends 参数,因此 Looker 会从被扩展的对象(在本例中为 orders_base 探索)的 LookML 元素开始。此时,label 值为“订单基础”。
  2. 对象细化中指定的 extends 中的值。由于 orders 具有细化,并且细化具有 extends 参数,因此 Looker 会应用细化扩展中的 LookML 元素,在本例中为 users_base Explore。此时,label 值为“用户基础”。
  3. 对象中的值。现在,所有扩展都已处理完毕,Looker 会应用扩展对象中的元素,在本例中,该对象是 orders 探索。如果存在任何冲突,则扩展对象胜出。现在,label 的值为“订单”。
  4. 对象细化的值。最后,Looker 会应用 orders 探索的任何细化中的元素。如果存在任何冲突,则以优化对象为准。现在,label 的值为“Orders Refined”。

优化标签 extends 可累加

如本页面的优化会替换参数部分中所述,优化通常会替换对象的原始设置。但 extends 参数并非如此。如果在优化中使用 extends,则 extends 参数中的值会附加到原始对象或之前优化中扩展的商品列表(如果有)。然后,如果存在任何冲突,则优先考虑扩展链中的最后一个项。

例如,以下是一个名为 orders_base 的基本探索和扩展该基本探索的 orders 探索。此外,还有users_base探索和+orders优化,可扩展users_base

explore: orders_base {
  view_name: orders
  extension: required
  # other Explore parameters
}

explore: users_base {
  view_name: users
  extension: required
  # other Explore parameters
}

explore: orders {
  extends: [orders_base]
  # other Explore parameters to build on the base Explore
}

explore: +orders {
  extends: [users_base]
  # other Explore parameters to build on the base Explores
}

orders 探索会扩展 orders_base,然后 +orders 细化会向 extends 列表添加 users_base。这样一来,+orders 探索现在将同时扩展 orders_baseusers_base,就像这是探索的原始 LookML 一样:

explore: orders {
  extends: [orders_base, users_base]
}

然后,如果存在任何冲突,则优先考虑扩展链中的最后一个项。在此示例中,users_base 中的元素会替换 orders_base 中任何冲突的元素。

如需了解一次性扩展多个对象的概念,请参阅通过 extends 重用代码文档页面。

最后需要注意的是,在此示例中,explore 参数的顺序无关紧要。不过,如果同一对象有多个细化,细化的顺序很重要。如本页面的细化按顺序应用部分中所述,文件中的最后一次细化会覆盖之前的细化。

在 LookML 项目中使用细化

以下是优化项目中的视图和探索的大致步骤:

  1. 确定要优化的视图或探索。
  2. 确定要将优化放置在何处。您可以在任何现有的 LookML 文件中添加优化,也可以为优化创建单独的 LookML 文件。(如需查看创建通用 LookML 文件的示例,请参阅了解其他项目文件文档页面上有关创建数据测试文件的步骤。)
  3. 使用 include 参数将细化纳入模型中:
    • 在您编写细化内容的文件中,必须包含您要细化的 LookML 文件。如果您尝试优化未包含的对象,Looker IDE 会向您发出警告。
    • 在模型文件中,添加定义了细化的文件。您可以将文件组合起来,并以极具创意的方式使用包含项;有关详情,请参阅此页面上的使用细化功能为模型添加层部分。

示例

无需修改原始 LookML,即可轻松调整视图和探索,从而优化 LookML 对象。当您的视图和 Explore 在项目中处于只读状态时(例如从其他项目导入的文件),此功能尤其有用。以下是优化探索的示例。

以下是 aircraft 探索的 LookML:


explore: aircraft {
  join: aircraft_types {
    type: left_outer
    sql_on: ${aircraft.id} = ${aircraft_types.id} ;;
    relationship: many_to_one
  }

  join: aircraft_engine_types {
    type: left_outer
    sql_on: ${aircraft.id} = ${aircraft_engine_types.id} ;;
    relationship: many_to_one
  }
}

此探索包含多个视图,每个视图都有许多维度。

现在,另一个名为 e_faa_refined 的 LookML 项目导入了 aircraft 探索文件。在 e_faa_refined 项目中,您可以使用优化来大幅简化 aircraft 探索。

由于 aircraft 探索是导入的文件,因此您无法直接修改它。不过,您可以为其添加优化。下面是一个名为 refinements.lkml 的单独文件的示例,其中包含以下 LookML:

include: "//e_faa_original/Explores/aircraft.explore.lkml"

explore: +aircraft {
  label: "Aircraft Simplified"
  fields: [aircraft.aircraft_serial, aircraft.name, aircraft.count]
}

refinements.lkml 文件包含以下内容:

  • include 参数,用于引入导入项目中的原始 aircraft.explore.lkml 文件(如需详细了解如何引用导入的项目文件,请参阅从其他项目导入文件文档页面)。
  • aircraft 探索功能的改进:
    • “探索”名称前面的 + 符号表示对现有探索的优化。
    • label 参数将“探索”的标签更改为“简化版飞机”。
    • fields 参数指定“探索”中将仅显示三个字段。

最终结果与以下原始的 aircraft 探索和 aircraft 视图相同:

explore: aircraft {
  label: "Aircraft Simplified"
  }

view: aircraft {
  sql_table_name: flightstats.aircraft ;;

  dimension: aircraft_serial {
    type: string
    sql: ${TABLE}.aircraft_serial ;;
  }

  dimension: name {
    type: string
    sql: ${TABLE}.name ;;
  }

  measure: count {
    type: count
  }
}

如需查看使用细化功能针对多种用例自定义单个视图的示例,请参阅通过 DRY LookML 最大限度提高代码可重用性:针对多种用例自定义单个基本视图实战宝典配方。

其他优化用例

如前所述,优化非常适合用于调整只读 LookML 对象,例如 Looker 模块导入的文件

不过,一旦您熟悉了如何添加细化并将其纳入模型中,就可以利用项目实现非常酷的效果,如以下示例中所述。

使用优化来添加分析

您可以使用细化功能向模型添加分析,而无需修改原始 LookML 文件。例如,如果某个项目中的视图和 Explore 是根据数据库中的表生成的,并存储在名为 faa_basic.lkml 的 LookML 文件中,您可以创建一个 faa_analysis.lkml 文件,并在其中使用细化来添加分析。以下是一个名为 distance_stats 的新派生表的示例,其中包含距离分析。此示例展示了对 faa_basic.lkml 文件中现有 flights 探索的改进,该改进将 distance_stats 派生表联接到 flights 探索中。此外,在示例底部,现有 flights 视图经过优化,添加了分析中的新字段:

include: "faa_basic.lkml"

explore: +flights {
  join: distance_stats {
    relationship: one_to_one
    type: cross
  }
}

view: distance_stats {
  derived_table: {
    explore_source: flights {
      bind_all_filters: yes
      column: distance_avg {field:flights.distance_avg}
      column: distance_stddev {field:flights.distance_stddev}
    }
  }
  dimension: avg {
    type:number
    sql: CAST(${TABLE}.distance_avg as INT64) ;;
  }
  dimension: stddev {
    type:number
    sql: CAST(${TABLE}.distance_stddev as INT64) ;;
  }
}
view: +flights {
  measure: distance_avg {
    type: average
    sql: ${distance} ;;
  }
  measure: distance_stddev {
    type: number
    sql: STDDEV(${distance}) ;;
  }
  dimension: distance_tiered2 {
    type: tier
    sql: ${distance} ;;
    tiers: [500,1300]
  }
}

使用细化功能为模型添加层

细化的另一个有趣的应用场景是为项目添加图层。您可以创建多个细化文件,然后有策略地添加这些文件以增加层次。

例如,在 FAA 项目中,有一个 faa_raw.lkml 文件,其中包含根据数据库中的表生成的所有视图和探索。此文件包含数据库中每个表的视图,每个视图都包含每个数据库列的维度。

除了原始文件之外,您还可以创建 faa_basic.lkml 文件来添加具有基本优化的新层,例如向探索添加联接,或向视图添加度量,如下所示:

include: "faa_raw.lkml"

explore: +flights {
  join: carriers {
    sql_on: ${flights.carrier} = ${carriers.name} ;;
  }
}

view: +flights {
  measure: total_seats {
    type: sum
    sql: ${aircraft_models.seats} ;;
  }
}

然后,您可以添加 faa_analysis.layer.lkml 文件以添加包含分析的新图层(有关分析文件示例,请参阅使用优化添加分析子部分)。

然后,您只需将所有细化文件纳入模型文件即可。您还可以使用模型文件来添加细化功能,以便将视图指向您要引用的数据库表:

connection: "publicdata_standard_sql"

include: "faa_raw.lkml"
include: "faa_basic.lkml"
include: "faa_analysis.lkml"

view: +flights {
  sql_table_name: lookerdata.faa.flights;;
}
view: +airports {
  sql_table_name: lookerdata.faa.airports;;
}
view: +aircraft {
  sql_table_name: lookerdata.faa.aircraft;;
}
view: +aircraft_models{
  sql_table_name: lookerdata.faa.aircraft_models;;
}
view: +carriers {
  sql_table_name: lookerdata.faa.carriers;;
}

您可以复制此模型文件并指向不同的数据库表,也可以添加您创建的不同细化文件,以定义模型中所需的其他层。

使用 PDT 的细化

如本页面的与扩展相比的细化部分中所述,扩展会创建被扩展对象的新副本。对于永久性派生表 (PDT),您不应使用扩展,因为 PDT 的每个扩展都会在数据库中创建一个新的表副本。

不过,您可以向 PDT 的视图添加细化条件,因为细化条件不会创建所细化对象的新副本。

使用元数据查看对象的精细化程度

您可以在 Looker IDE 中点击 exploreview 参数,然后使用元数据面板查看对象的任何优化。如需了解相关信息,请参阅 LookML 对象的元数据文档页面。

注意事项

包含本地化的项目

在优化对象时,请注意本地化规则也适用于您的优化。如果您要优化对象,然后定义新的标签或说明,则应在项目的语言区域字符串文件中提供本地化定义。如需了解详情,请参阅本地化 LookML 模型文档页面。