Community

動的な階層の作り方

階層は値をバケット化するのに最適な方法ですが、LookMLのdimensionのtier:で指定した場合は、バケットのサイズは事前定義された静的な階層となります。時折、バケットサイズを動的に変更可能な階層を作成したい場合があります。これを、Liquidと呼ばれるテンプレート言語と、パラメーターと呼ばれるLookerのフィルターのみのフィールドを使用して実現可能です。
(:us:本記事は、このヘルプ記事を翻訳したものになります)

実現方法

  • まず、ユーザーが希望するバケットサイズの数値を入力するためのフロントエンドフィルターフィールドとして機能するパラメータ(type: number)を作成します。
  • 次に、さまざまなバケットを決定するために使用されるディメンションにて、Liquid変数{% parameter parameter_name %}で前述のパラメーター値を参照します。 これにより、ユーザーがパラメータに入力した値に応じて、dimensionの出力内容が動的に変更されます。


動的階層を構築するために、モジュロ演算を使用するパターンを作成します。そうすると、以下のように、10〜20、20〜30などの階層が連結した状態で表示されます。

数学的アプローチ:
先に述べたように、 剰余演算(modや%)を使用して階層を計算します。このアプローチは、いくつかの簡単な数学で説明できます。

  • rが、ユーザー定義のバケットサイズを表すとする
  • バケットを割り当てたい値を、nとする

まず、次の式でバケットの下限を計算します:

n - n % r

次に、次の式で上限を計算します:

n - n % r + r

例:

r = 5
n = 33
n % r = 33 % 5 = 3

これは以下のことを意味します:

下限境界 = 33 - 3 = 30
上限境界 = 33 - 3 + 5 = 35

次に、これらの2つの値を連結すると、30 - 35 という階層が得られます。

LookMLで実装する場合
最初に、エンドユーザーが希望するバケットサイズを選択できるようにするパラメーターを作成します:

parameter: bucket_size {
  default_value: "10"
  type: number
}

次に、bucket_sizeパラメータからユーザーの入力値を受け取り、同じバケットサイズになるよう計算するdimensionを構築します。

dimension: dynamic_bucket  {
  sql:  
      concat(${sale_price} - mod(${sale_price},{% parameter bucket_size %}),
      '-', ${sale_price} - mod(${sale_price},{% parameter bucket_size %}) 
           + {% parameter bucket_size %})
  ;;
  order_by_field: dynamic_sort_field   
}

このdimensionの使い辛い点の1つとして、文字列であるがゆえに、並べ替えの問題を引き起こす可能性があることです。例えば、バケットに昇順の並べ替えを適用した場合、100-110 は 90-100 の前になってしまいます。このため、ディメンションをどのように並べ替えるかを決定する並べ替えフィールドを作成する必要があります。

dimension: dynamic_sort_field {
  sql: 
      ${sale_price} - mod(${sale_price},{% parameter bucket_size %});;
  type: number
  hidden: yes
}

並べ替えフィールドが文字列ではなく数値になっているため、動的バケット列は意図したとおりにソートされます。また、このディメンションにはバケットと同じカーディナリティがあるため、結果セットがファンアウトしないことが保証されます。ファンアウトの詳細については、この投稿をご覧ください。

以上となります。心おもむくままに、バケット化しましょう!