testパラメータ使ってみる~あなたのExplore正しい値を示してますか?~ #looker

2020.12.06

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

※本エントリは、Looker Advent Calendar 2020の6日目のエントリです。

Lookerでは、グラフを作成する際に必ずLookMLでexploreを定義する必要があります。 exploreでは複数のviewをJOINすることもできるため、exploreの内容が複雑になってくると、「このexplore、本当に正しい値を出せているのかな…」と不安になる方もいるのではないかと思います。

そんなときに、Lookerではtestというパラメータがあり、これを使うことで作成したexploreが正しい値を出すことが出来ているか、LookMLのIDE上でvalidationの際に確認することが出来ます。

本エントリでは、このtestパラメータの仕様と事例について説明します。

仕様

testパラメータは、Explore上で発行されるクエリを定義し(explore_sourceで定義)、testの合否を決める条件式を定め(assertで定義)、クエリの結果が定めた条件式と一致していたら、問題なくproductionモードへデプロイ出来るようになる、という機能を持つパラメータです。

実際には、下記のようにexplore_sourceassertというサブパラメータを用いて定義します。

test: historic_revenue_is_accurate {
  explore_source: orders {
    column: total_revenue {
      field: orders.total_revenue
    }
    filters: [orders.created_date: "2017"]
  }
  assert: revenue_is_expected_value {
    expression: ${orders.total_revenue} = 626000 ;;
  }
}

explore_sourceでは、実際にExplore上で発行されるクエリをイメージして、記述します。(ネイティブ派生テーブルのexplore_sourceと同じ書き方ですね。)

assertでは、前述のexplore_sourceで定義したフィールドを用いて、yes/noを返す条件式を1つ記述します。この条件式がyesであれば、このtestをクリアしたとみなされます。

注意点

testパラメータを使う際は、1つ注意点があります。

それは、対象のプロジェクトの設定画面において、「Require data tests to pass before deploying this project to production.」にチェックを入れておくことです。

ここにチェックを入れておかないと、せっかくtestパラメータを定義しても、testをクリアしていないのにproductionモードにデプロイ出来るようになってしまいます。

実際には、チェックを入れておくことでLookML IDEの右上のGit関係の操作を行うボタンが下図のように遷移します。「Run Tests」が「Commit Changes & Push」の後に加わる形ですね。

このためtestをクリアしないと、Pull Requestsの発行や、productionモードへのMergeができなくなります。

確実に設定したtestを適用するため、testパラメータを使う前には必ずこの設定にチェックを入れるようにしましょう!!

公式Doc

testパラメータに関する公式Docもありますので、ぜひこちらもご確認ください。

活用事例

testパラメータの仕様の説明だけだとわかりづらいと思うため、実際に本番環境でも使うことが出来ると思う事例を3つ紹介します。

設定したprimary_keyが一意であるか確認

Lookerではどのviewを定義する際でも、ある1行のレコードを一意に表すことのできるprimary_keyを定義することを推奨しています。

このprimary_keyの定義に加えてrelationshipの定義もしていることで、Lookerの強みの一つであるシンメトリック集計を行うことが出来るようになるため、primary_keyを各viewに設定することはとても重要です。

この「primary_keyが正しく設定出来ているか」の検証に、testパラメータを活用することができます。

実例

primary_keyが正しく設定出来ているかの検証を行う場合には、以下のようにtestパラメータを記述します。

test: order_id_is_unique {
  explore_source: order_items {
    column: id {}
    column: count {}
    sorts: [order_items.count: desc]
    limit: 1
  }
  assert: order_id_is_unique {
    expression: ${order_items.count} = 1 ;;
  }
}

この例では、order_itemsというexploreに対して、idというディメンションをprimary_keyに設定しているとします。

まずexplore_sourceでは、idと、それぞれのidがいくつあるか集計するためのcount、この2つのフィールドを定義します。この上で、結果を降順で表示するようにsortして、limitで先頭の1行だけ出力するようにします。

続いてassertでは、countの結果が1であること、を条件として定義します。

これにより、primary_keyとしてidが適切であればcountの値はどのidでも1になりtestをクリア出来ますが、もし重複するidがあれば2以上の値を返すためtestをクリア出来なくなり、primary_keyが適切に設定されていることを確認できるようになります。

すでに値が固まっている過去実績の集計値の確認

次に、すでに値が定まっている過去の実績の集計値の確認を、testパラメータを用いて行っていきます。

「過去の実績なんてわかっているし、testする意味あるの?」と思う方もいるかもしれませんが、すでに値が固まっている集計値を確認することは重要です。

例えば以下のような場合には、過去の実績であっても異なる値を表示してしまうと思います。

  • 接続先のデータにて、過去の実績を書き換える処理が発生した
  • 複数のviewをJOINしたexploreのとき、シンメトリック集計が上手く動いていない

こういった場合があるため、常に正しい値をexploreで出せるようにするために過去の実績値をtestパラメータで確認することは意義があると、私は考えています。

実例

すでに値が固まっている過去の実績の値にずれが無いか確認するには、以下のようにtestパラメータを記述します。

test: historic_revenue_is_accurate {
  explore_source: order_items {
    column: total_sales {
      field: order_items.total_sales
    }
    filters: [order_items.created_date: "2017"]
  }
  assert: revenue_is_expected_value {
    expression: ${order_items.total_sales} = 1772357.1264990754 ;;
  }
}

まずexplore_source上では、売上合計値を示すtotal_salesを用いて、過去年の2017年でフィルタをしてしまいます。

続いてassertでは、2017年のtotal_salesに値する「1772357.1264990754」を指定します。

これにより、何かしらの影響によって過去年である2017年のtotal_salesの数値がズレてしまった場合、testをクリアできなくなるので、productionモードにデプロイする前に異常を検知することが出来るようになります。

すでに値が固まっている過去実績の集計値の確認(複数viewの結合ver)

先程の例では、単一のviewでの過去実績の集計値の確認を行いました。

しかし、Lookerのexploreでは複数のviewをJOINしている場合、そのJOINしているviewのフィールドを1つでも選択していないとJOINが行われません。

そのため、複数のviewをJOINしているときには、どうやってtestパラメータを記述するのかを続けて説明します。

実例

複数のviewのJOINを行った後でも、過去の実績の値が問題なく表示されるかを確認するためには、以下のようにtestパラメータを記述します。

test: historic_revenue_is_accurate {
  explore_source: order_items {
    column: total_sales {
      field: order_items.total_sales
    }
    column: count {
      field: distribution_centers.count
    }
    filters: [order_items.created_date: "2017"]
  }
  assert: revenue_is_expected_value {
    expression: ${order_items.total_sales} = 1772357.1264990754 ;;
  }
}

先程の単一のviewの場合との違いは、explore_source内で別のviewのメジャーを追加していることです。

ここで選択する別のviewのメジャーは、元のorder_itemsのexploreの定義上、最後にJOINを行っているdistribution_centersのメジャーを用いています。

これにより、関係する全てのviewのJOINを完了した状態で、過去実績の値が問題なく表示されるかを確認できます。 シンメトリック集計が正しく動いているかの確認にも良いですね!

ちなみに、ここで別のviewのディメンションを定義してしまうと、そのディメンションごとに集計値が別れてしまい、全レコードの集計値を用いたtestが出来なくなってしまうためオススメしません。

最後に

いかがでしたでしょうか!

testパラメータを用いてexploreの内容を検証できるようにすることで、より確実に正確な値をユーザーへ届けることが可能になると思います。

これは余談ですが、私がTableauをよく使用していたとき、複雑なデータ処理をTableau Prepで行った際にデータに不備がないか確認するため、加工前&加工後それぞれのデータで一度同じグラフを書いて、あるメジャーの値に変動がないか、を自分の手作業で確認していました。

そのため、Lookerのこのtestパラメータを知ったとき、「おっ、これは便利だ!自分でグラフ作って検証する必要がなくなるぞ!」と感じました。私はとても便利な機能だと思っています!

ぜひ、皆さんの環境でもtestパラメータを使ってみてください!