Refinamentos do LookML

Vista geral

Com os refinamentos do LookML, pode adaptar uma vista ou uma exploração existente sem editar o ficheiro LookML que a contém. Isto é ideal para:

Por exemplo, se tiver o seguinte ficheiro de visualização no seu projeto:

view: flights {
  sql_table_name: flightstats.accidents ;;

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

Pode refinar a vista flights, conforme mostrado no exemplo seguinte: use o parâmetro view com o mesmo nome da vista, mas adicione um sinal de mais (+) antes do nome para indicar que se trata de um refinamento de uma vista existente.

Este refinamento adiciona uma dimensão air_carrier à vista flights existente:

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

Este refinamento pode ser colocado em qualquer ficheiro LookML no projeto, como um ficheiro de modelo, um ficheiro de visualização ou no seu próprio ficheiro LookML dedicado. Consulte a secção Usar refinamentos no seu projeto do LookML para saber como funciona.

O refinamento combinado com o LookML original tem o resultado final como se fosse o LookML original para a vista:

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 ;;
  }
}

Na IU do Looker, os utilizadores veem a dimensão Transportadora aérea, tal como se tivesse adicionado a dimensão ao próprio ficheiro de visualização original.

Consulte a secção Exemplo para ver informações de implementação mais detalhadas.

Refinamentos em comparação com extensões

O Looker também suporta a extensão de objetos LookML. A extensão é útil quando quer criar uma nova cópia de uma vista ou de uma exploração existente para poder adicionar-lhe novos objetos. Por exemplo, pode criar uma visualização de propriedade base que defina todos os seus campos e, em seguida, criar várias novas visualizações de propriedade que expandam a visualização de propriedade base. Em seguida, estas novas vistas podem ser modificadas para ocultar determinados campos na vista base ou para alterar as definições ou as etiquetas dos campos da vista base.

Os refinamentos são úteis quando quer modificar uma vista ou uma análise detalhada existente com algumas alterações ou ajustes a determinados objetos, mas não quer criar cópias da vista ou da análise detalhada. Os refinamentos são ideais para situações em que não pode ou não quer modificar a vista base ou o Explorar, e para situações em que a criação de uma nova vista ou de um novo Explorar exigiria alterações extensivas a outras referências do LookML. Consulte a secção Exemplo nesta página para ver um exemplo deste exemplo de utilização.

Para a maioria dos exemplos de utilização, os refinamentos são uma alternativa mais simples e organizada à extends.

Os programadores de LookML avançados podem querer usar o parâmetro extends numa otimização de LookML. Consulte a secção Os refinamentos podem conter extensões nesta página para mais informações.

Os refinamentos substituem a maioria dos parâmetros

É importante ter em atenção que, na maioria dos casos, um refinamento substitui as definições originais de um objeto. No exemplo seguinte, a vista original tem uma dimensão oculta (hidden: yes):

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

E noutro ficheiro, existe um refinamento dessa dimensão com hidden: no:


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

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

O último refinamento tem precedência, pelo que hidden: no é aplicado e a dimensão é apresentada na vista final.

Existem alguns casos em que os refinamentos são aditivos em vez de substituírem; consulte a secção Alguns parâmetros são aditivos desta página para mais informações.

Alguns parâmetros são aditivos

Em muitos casos, se o refinamento contiver o mesmo parâmetro que o objeto a ser refinado, o refinamento substitui os valores dos parâmetros do objeto refinado.

No entanto, os refinamentos podem ser aditivos para alguns parâmetros, o que significa que os valores do objeto base são usados em conjunto com os valores do objeto refinado.

Os seguintes parâmetros são aditivos:

Por exemplo, segue-se uma vista que tem uma dimensão name com um parâmetro link:

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"
    }
  }
}

Segue-se um refinamento da vista carriers, com uma dimensão name que tem valores diferentes para o parâmetro 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"
    }
  }
}

Na vista carriers refinada, os dois parâmetros link são aditivos, pelo que a dimensão name apresenta ambos os links.

Os refinamentos são aplicados por ordem

Um objeto pode ser refinado várias vezes e em vários locais, o que permite aos programadores do Looker usar refinamentos de muitas formas criativas. No entanto, isto também significa que os programadores têm de ter muito cuidado com a ordem em que os refinamentos são aplicados:

  • Num projeto, os refinamentos são aplicados pela ordem em que os respetivos ficheiros são incluídos. Os refinamentos dos ficheiros incluídos por último substituem os refinamentos dos ficheiros incluídos anteriormente.
  • Num único ficheiro, os refinamentos são aplicados linha a linha para baixo. Os refinamentos com o número de linha mais elevado são aplicados por último e substituem quaisquer refinamentos anteriores, se existirem conflitos.

Por exemplo, no ficheiro de visualização seguinte, existem dois refinamentos da visualização faa_flights. O primeiro refinamento oculta uma dimensão (hidden: yes) e o segundo refinamento apresenta a dimensão (hidden: no). Quando existem conflitos como este, o refinamento mais abaixo no ficheiro tem precedência:

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

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

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

A lógica é semelhante para incluir vários ficheiros num projeto: os refinamentos no último ficheiro indicado nas inclusões têm precedência. Por exemplo, se um ficheiro de modelo incluir estes ficheiros:

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

Os refinamentos no ficheiro distance_analysis.lkml são aplicados primeiro e, em seguida, são aplicados os refinamentos no ficheiro finishing_touches.lkml. Se existirem conflitos, os refinamentos no último ficheiro, finishing_touches.lkml, têm precedência.

Usar final: yes para impedir mais refinamentos

Conforme descrito anteriormente, o mesmo objeto pode ser refinado várias vezes em vários locais e o último refinamento substitui todos os refinamentos anteriores.

Se tiver um refinamento que quer que seja considerado o refinamento final para a vista ou a funcionalidade Explorar, pode adicionar a flag final: yes ao refinamento. O IDE do Looker devolve um erro LookML se existirem refinamentos que seriam aplicados após este refinamento final ou se um programador tentar adicionar um novo refinamento que seria aplicado após este refinamento final. Por exemplo, o segundo refinamento neste ficheiro de visualização criaria um erro de LookML porque o refinamento anterior tem a flag 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
  }
}

Adicionar a flag final: yes a um refinamento é uma boa forma de verificar se os refinamentos estão a ser aplicados na ordem pretendida.

Os refinamentos podem conter extensões

Os programadores de LookML avançados podem querer usar um parâmetro extends numa refinação de LookML, que adiciona o objeto expandido ao objeto que está a ser refinado.

Para resumir o comportamento de extends e refinamentos:

  • A extensão de um objeto cria uma nova cópia do objeto e, em seguida, baseia-se nela. Por exemplo, pode criar uma visualização de propriedade base que defina todos os seus campos e, em seguida, criar várias novas visualizações de propriedade que expandam a visualização de propriedade base. Cada uma destas novas visualizações de propriedade incorpora uma cópia da visualização de propriedade base e, a partir daí, um programador pode adicionar diferentes campos, filtros ou outras propriedades para modificar o que está na visualização de propriedade base. A ideia é começar com um objeto base e, em seguida, usá-lo de diferentes formas noutros objetos. (Pode consultar a página de documentação Reutilizar código com extends para uma discussão completa sobre como trabalhar com extends.)
  • Refinar um objeto adiciona uma camada de modificações ao objeto, mas, ao contrário da extensão, o refinamento não cria várias cópias do objeto. A ideia é criar um objeto base sem modificar o respetivo LookML original.

Como exemplo da utilização padrão de refinamentos, segue-se uma exploração denominada orders e a exploração +orders que a refina:

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

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

Além disso, pode adicionar um refinamento que inclua um extends. Com base no exemplo, aqui está a mesma ordersexploração. No entanto, além disso, existe uma análise detalhada base denominada users_base e, agora, o refinamento +orders tem um parâmetro extends que apresenta a 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
}

O que é especial aqui é que o refinamento +orders tem um extends. O resultado é que a vista +orders vai agora expandir a funcionalidade users_base Explorar.

Como o Looker implementa extends em refinamentos

A extensão de um objeto num refinamento é um conceito avançado do LookML. Antes de usar extends num refinamento, deve ter um conhecimento profundo do seguinte:

  • Como o Looker implementa extends: se um elemento LookML for definido no objeto estendido e no objeto de extensão, é usada a versão no objeto de extensão, a menos que o parâmetro seja aditivo. Consulte a página de documentação Reutilizar código com extends para ver detalhes.
  • Como o Looker implementa os refinamentos: se um elemento LookML for definido em vários refinamentos, o último refinamento substitui os refinamentos anteriores. Consulte a secção Os refinamentos são aplicados por ordem nesta página para ver detalhes.

Por último, deve compreender como o Looker combina estes princípios para implementar extends usados nos refinamentos. Segue-se a ordem de implementação do Looker, com cada passo a substituir o anterior em caso de conflitos:

  1. Valores do extends especificado no objeto
  2. Valores do extends especificado nos refinamentos do objeto
  3. Valores do objeto
  4. Valores dos refinamentos do objeto

Para ilustrar, aqui está um exemplo que acompanha o valor do parâmetro label em cada passo da implementação:

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]
}

Veja como o Looker implementa o valor de label para a exploração orders neste exemplo:

  1. Valores do extends especificado no objeto. Uma vez que a ordersexploração tem um parâmetro extends, o Looker começa com os elementos LookML do objeto que está a ser expandido, que, neste caso, é a orders_baseexploração. Neste momento, o valor de label é "Base de encomendas".
  2. Valores do extends especificado nos refinamentos do objeto. Uma vez que orders tem um refinamento e o refinamento tem um parâmetro extends, o Looker aplica então elementos LookML da extensão do refinamento, que, neste caso, é o conteúdo de Explorar users_base. Neste momento, o valor de label é "Base de utilizadores".
  3. Valores do objeto. Agora que todas as extensões foram abordadas, o Looker aplica elementos do objeto de extensão, que, neste caso, é a orders exploração. Se existirem conflitos, o objeto de extensão prevalece. Assim, agora, o valor label é "Encomendas".
  4. Valores dos refinamentos do objeto. Por último, o Looker aplica elementos de quaisquer refinamentos do orders Explorar. Se existirem conflitos, o objeto de refinamento vence. Assim, agora, o valor label é "Pedidos refinados".

Os refinamentos extends são cumulativos

Conforme descrito na secção Os refinamentos substituem os parâmetros nesta página, os refinamentos geralmente substituem as definições originais de um objeto. Este não é o caso do parâmetro extends. Quando extends é usado num refinamento, o valor no parâmetro extends é anexado à lista de itens expandidos no objeto original ou em refinamentos anteriores, se existirem. Em seguida, se existirem conflitos, é dada prioridade ao último item na cadeia de extensões.

Por exemplo, aqui está uma exploração base denominada orders_base e uma exploração orders que expande a base. Além disso, existe a users_base exploração e o refinamento +orders que se estende 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
}

A opção orders Explorar expande a opção orders_base e, em seguida, os refinamentos +orders adicionam a opção users_base à lista extends. O resultado é que o +orders Explore vai agora estender orders_base e users_base, como se este fosse o LookML original para o Explore:

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

Em seguida, se existirem conflitos, é dada prioridade ao último item na cadeia de extensões. Neste exemplo, os elementos em users_base substituem quaisquer elementos em conflito em orders_base.

O conceito de extensão de mais do que um objeto de cada vez é abordado na página de documentação Reutilizar código com extends.

Última nota: neste exemplo, a ordem dos parâmetros explore não é importante. No entanto, nos casos com vários refinamentos do mesmo objeto, a ordem dos refinamentos é importante. Conforme descrito na secção Os refinamentos são aplicados por ordem desta página, o último refinamento num ficheiro substitui os refinamentos anteriores.

Usar refinamentos no seu projeto do LookML

Seguem-se os passos gerais para refinar as vistas e as explorações no seu projeto:

  1. Identifique a vista ou a funcionalidade Explorar que quer refinar.
  2. Decida onde quer alojar os refinamentos. Pode adicionar refinamentos a qualquer ficheiro LookML existente ou criar ficheiros LookML separados para os refinamentos. (Consulte o procedimento para criar um ficheiro de teste de dados na página de documentação Compreender outros ficheiros do projeto para ver um exemplo de criação de ficheiros LookML genéricos.)
  3. Use o parâmetro include para incorporar os seus refinamentos no modelo:
    • No ficheiro onde escreve os refinamentos, tem de incluir os ficheiros do LookML que está a refinar. O IDE do Looker apresenta avisos se tentar refinar um objeto que não esteja incluído.
    • No ficheiro do modelo, inclua os ficheiros onde as suas otimizações estão definidas. Pode combinar ficheiros e usar inclusões de formas muito criativas. Consulte a secção Usar refinamentos para adicionar camadas ao seu modelo nesta página para ver detalhes.

Exemplo

Refinar objetos LookML é uma forma fácil de adaptar vistas e explorações sem ter de editar o LookML original. Isto é especialmente útil quando as suas vistas e explorações são só de leitura no seu projeto, como com ficheiros importados de outros projetos. Segue-se um exemplo de como refinar uma análise detalhada.

Aqui está o LookML para a exploração aircraft:


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
  }
}

Esta análise detalhada contém várias vistas, cada uma com muitas dimensões.

Agora, outro projeto do LookML denominado e_faa_refined importa o ficheiro de exploração aircraft. No projeto e_faa_refined, pode usar um refinamento para simplificar drasticamente a aircraftExploração.

Uma vez que o ficheiro aircraft Explorar é um ficheiro importado, não o pode editar diretamente. Em alternativa, pode adicionar-lhe um refinamento. Segue-se um exemplo de um ficheiro separado denominado refinements.lkml que contém este LookML:

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

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

O ficheiro refinements.lkml contém o seguinte:

  • O parâmetro include para importar o ficheiro aircraft.explore.lkml original do projeto importado (consulte a página de documentação Importar ficheiros de outros projetos para ver detalhes sobre como fazer referência a ficheiros de projetos importados).
  • Refinamentos da secção aircraft Explorar:
    • O sinal + antes do nome da exploração indica um refinamento de uma exploração existente.
    • O parâmetro label altera a etiqueta do Explore para "Aircraft Simplified" (Aeronave simplificada).
    • O parâmetro fields especifica que apenas três campos são apresentados na funcionalidade Explorar.

O resultado final é como se fosse a vista aircraft Explorar e aircraft original:

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
  }
}

Para ver um exemplo de utilização de refinamentos para personalizar uma única vista para vários exemplos de utilização, consulte a receita do livro de receitas Maximizar a reutilização de código com DRY LookML: personalizar uma única vista base para vários exemplos de utilização.

Outros exemplos de utilização de refinamentos

Conforme mencionado anteriormente, os refinamentos são ideais para adaptar objetos LookML só de leitura, como blocos do Looker ou ficheiros importados.

No entanto, assim que se habituar a adicionar refinamentos e incluí-los nos seus modelos, pode fazer coisas muito interessantes com os seus projetos, conforme descrito nos exemplos seguintes.

Usar refinamentos para adicionar análises

Pode usar refinamentos para adicionar análises ao seu modelo sem alterar os ficheiros LookML originais. Por exemplo, se existir um projeto em que as vistas e as explorações são geradas a partir de tabelas na sua base de dados e armazenadas num ficheiro LookML denominado faa_basic.lkml, pode criar um ficheiro faa_analysis.lkml onde usa refinamentos para adicionar análises. Segue-se um exemplo de uma nova tabela derivada denominada distance_stats que tem uma análise de distância. Este exemplo mostra um refinamento do flights Explore do ficheiro faa_basic.lkml que junta a tabela derivada distance_stats ao flights Explore. Além disso, na parte inferior do exemplo, a vista flights existente é refinada para adicionar novos campos da análise:

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]
  }
}

Usar refinamentos para adicionar camadas ao seu modelo

Outro exemplo de utilização interessante dos refinamentos é adicionar camadas ao seu projeto. Pode criar vários ficheiros de refinamento e, em seguida, incluí-los estrategicamente para adicionar camadas.

Por exemplo, no projeto FAA, existe um ficheiro faa_raw.lkml que contém todas as visualizações e explorações que foram geradas a partir de tabelas na sua base de dados. Este ficheiro tem uma vista para cada tabela na base de dados, cada uma com uma dimensão para cada coluna da base de dados.

Além do ficheiro não processado, pode criar um ficheiro faa_basic.lkml para adicionar uma nova camada com refinamentos básicos, como adicionar junções aos seus Explorar ou adicionar medidas às suas vistas, da seguinte forma:

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} ;;
  }
}

Em seguida, pode adicionar um ficheiro faa_analysis.layer.lkml para adicionar uma nova camada com análises (consulte a subsecção Usar refinamentos para adicionar análises para ver um exemplo de um ficheiro de análise).

A partir daí, só tem de incluir todos os ficheiros de refinamento no ficheiro do modelo. Também pode usar o ficheiro do modelo para adicionar refinamentos que apontem as suas vistas para as tabelas da base de dados que quer referenciar:

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;;
}

Pode duplicar este ficheiro de modelo e apontar para diferentes tabelas de base de dados ou pode incluir diferentes ficheiros de refinamento que criou para definir outras camadas que quer no seu modelo.

Usar refinamentos para PDTs

Conforme descrito na secção Refinamentos em comparação com extensões desta página, uma extensão cria uma nova cópia do objeto que está a ser estendido. No caso das tabelas derivadas persistentes (PDTs), não deve usar extensões, uma vez que cada extensão de uma PDT cria uma nova cópia da tabela na sua base de dados.

No entanto, pode adicionar refinamentos à vista do PDT, uma vez que os refinamentos não criam uma nova cópia do objeto que está a ser refinado.

Usar metadados para ver refinamentos de um objeto

Pode clicar num parâmetro explore ou view no IDE do Looker e usar o painel de metadados para ver os refinamentos no objeto. Consulte a página de documentação Metadados para objetos do LookML para ver informações.

Aspetos a considerar

Projetos com localização

Quando refina um objeto, tenha em atenção que as regras de localização também se aplicam aos seus refinamentos. Se estiver a refinar um objeto e, em seguida, a definir novas etiquetas ou descrições, deve fornecer definições de localização nos ficheiros de strings de local do seu projeto. Consulte a página de documentação Localizar o seu modelo LookML para mais informações.