はじめまして、Gaudiyでアナリティクスエンジニア(副業)をしているkuwakenです。
Gaudiyでは現在、データの民主化を進めていますが、その過程でSQLを書く手間や負担、新しいBizメンバーのオンボーディングなどの面で、課題が生じていました。
今回は、その課題を解決するために導入した、dbt Semantic LayerとSteepという2つのデータ系プロダクトに関するお話をします。
1. dbt Semantic Layerの導入背景
Gaudiyでは、Gaudiy Fanlinkというファンコミュニティプラットフォームを開発・提供しており、ビジネスサイドのメンバーもデータの抽出や分析を自ら行える環境づくりに取り組んできました。
その「データの民主化」を推進する過程で、以下のような課題に直面していました。
SQLの手間と負担: チームメンバーはSQLを書くスキルを持っているものの、データ自体のドメイン知識を定着させるのに苦労しており、ちょっとしたクエリの修正や新規作成には時間がかかりがちでした。また、これをレビューしてもらうのは心理的な負担も伴っていました。
Bizメンバーのサポート: 新しく入ったビジネスサイドのメンバーが、自分たちで迅速にデータを集計・分析できる環境が必要でしたが、現状の仕組みでは、データの抽出や分析に専門知識が必要で、自立してデータを扱うことが難しくなっていました。
これらの課題を解決するため、私たちはセマンティックレイヤーの導入を検討開始しました。
詳細は割愛しますが、この分野は老舗ではLookerがあったり、最近ではファーストパーティのこのような情報もあったり、話題を耳にすることが多いです。
Gaudiyでは、BigQuery + dbt Cloudという構成であったため、dbt Semantic Layerを導入することにしました。
2. Steep導入の決定理由
次に、BIツールについてです。そもそも私が「Steep」というBIツールをはじめて知ったのは、確かこちらの記事だったと記憶しています。
本プロジェクトの比較検討フェーズにおいて他のBIも検討しましたが、Steep導入を決定した理由は、以下の4つです。
- モダンなUIと使いやすい操作性
- スマホアプリによる場所を選ばないデータ分析
- dbt Semantic Layerとの連携によるスムーズなデータ連携
- リーズナブルな価格
ただ、新しいものであるがゆえに、導入フェーズではいくつかの課題にも直面しました。
- セットアップ時に、dbt Cloudのus1リージョンを選択できなかった
- 値が存在しない日にもグラフが表示され、誤った傾向を示してしまう
- dbt側のMetricsでfilterを指定すると、Steepが発行するSQLに構文エラーが発生してしまうことがある(原因調査中)etc...
しかし、このようなバグレポートに対し、早いものでは即日対応してもらえたりするところは、やはり新興ツールならではのメリットだと思いました。一緒に製品を良くしていきたいというスタンスでいます。
3. dbt Semantic Layerに関するナレッジ
基本的にdbt Labsが提唱しているベストプラクティスにしたがって構築しましたが、実際にやってみてポイントだなと思った点をいくつかご紹介します。
3-1. ディレクトリ構造
dbtでセマンティックレイヤーを構築するには、semantic_models(measure, dimension)とmetricsをYAMLファイル内で定義する必要があります。
semantic_modelsとmetricsは同じYAMLファイルに書いても良いですし(通常のschema.yml内に記述することも可能)、metricsだけ別ファイルに切り出すのも良いらしく、その分け方も部署やエンティティなどさまざまなようです。
Gaudiyでは現在/models/semantic_models
, /models/metrics
の直下に格納しています。
models ├── (通常のモデルディレクトリ) ... ├── metrics │ ├── met_hoge.yml │ ├── ... │ └── met_fuga.yml └── semantic_models ├── metricflow_time_spine.sql ├── sem_piyo.yml ├── ... └── sem_hogera.yml
ただ、これでは数が増えてきた際に困りそうなので、さらにディレクトリを掘ろうかと考えているところです。
3-2. dbt Cloud CLI
本記事を執筆している時点(2024年5月)では、dbt Cloud IDEで出来ないことがあります。
- ◯ Semantic Modelsなどのプレビュー、コンパイル、リネージ閲覧
- × dbt-metricflowのコマンドを実行する
- × 開発環境でセマンティックレイヤーを構築する
とくに3番目は困りもので、本番環境にデプロイしてからでないと検証ができないということになります。
そこでローカルでdbt Cloud CLIを使用して開発を行っています。
$ dbt compile $ dbt sl query --metrics <metric_name> --group-by <dimension_name>
のようにコマンドを打つことで、開発中でもデータ取得が可能です。
3-3. 時間のdimensionはdatetime型で揃える(BigQueryユーザーのみ)
BigQueryでは、時間に関するdimensionを定義する際はdatetime型に揃えておく必要があります(URL)。もし異なるデータ型であれば、semantic_models内でexpr
でキャストしておけば良いです。
3-4. entitiesを理解する
entitiesが一番苦戦しました。最初は「そもそもこれは何なのか、別になくても良いのでは?」くらいに思っていましたが、とんでもありません。これがないと結合ができないのです。
たとえば以下のようにfct_orders
とdim_customer
という2つのモデルを、dim_customer_sk
というサロゲートキーで結合できるようにし、Steep上で「特定のカスタマーの注文合計を見たい」というニーズに応えたい場合、Gaudiyではこのように記述します。
# models/semantic_models/sem_fct_orders.yml semantic_models: - name: fct_orders label: fct_orders description: 注文に関するファクトテーブル model: ref('fct_orders') defaults: agg_time_dimension: order_date # --- entities --- entities: - name: fct_orders type: primary expr: fct_orders_sk - name: dim_customer # カラム名は変わる可能性があるので、別名にして抽象化するようにしています type: foreign # 外部キーであることを宣言 expr: dim_customer_sk # 実際のカラム名 (以下略) # --- measures --- measures: - name: order_total label: order_total description: 注文合計 agg: sum expr: amount (以下略)
# models/semantic_models/sem_dim_customer.yml semantic_models: - name: dim_customer label: dim_customer description: 顧客に関するdimensionテーブル model: ref('dim_customer') # --- entities --- entities: - name: dim_customer # sem_fct_ordersの方のentitiesと名前を揃えることで、結合スタンバイOKな状態になります type: primary expr: dim_customer_sk # --- dimensions --- dimensions: - name: customer_id label: customer_id description: 顧客ID expr: id type: categorical (以下略)
# models/metrics/met_fct_orders.yml metrics: - name: order_total label: order_total description: 注文合計 type: simple type_params: measure: name: order_total fill_nulls_with: 0 # NULLを0埋めできる
これをSteepで表示すると、横軸にorder_date
、縦軸にorder_total
のシンプルな時系列グラフが表示され、customer_id
でフィルターをかけることができるようになります。ちなみにdaily, weekly, monthlyなどの粒度の切り替えはSteep上で行えますので、別途モデルを作る必要はありません。
4. 今後やりたいこと
今後やっていきたいこととしては、3点あります。
各種モデルの拡充:
今回のプロジェクトではSemantic ModelsやMetricsの他に、その前段のベースとなるfactモデルやdimensionモデルのリファクタリング・新規追加を行いました。これらをさらに推し進め、より多くのディメンション・指標を扱えるようにします。ダッシュボードの整備:
Steepに関して、現状はMetricsページ(探索用)のみ社内公開していますが、順次ダッシュボードを作成していこうと考えています。その際はTeams機能を使用して組織単位などでページを分けることになると想定しています。Semantic ModelsとMetricsファイルの効率的な管理方法の模索:
前述の通り、ディレクトリ構造についてはまだまだ改善の余地があると思っています。複数ドメインをまたいでも適切に管理できるよう、整備していきたいと考えています。
また、Semantic Models/Metricsの記述〜Steep側の更新反映までのプロセスを半自動化させたいとも考えており、新たなOSSライブラリが生えてこないかアンテナを張りつつ、なければ内製で用意することも視野に入れています。
5. さいごに
今回取り上げたdbt Semantic LayerとSteepは、まだ開発途上の段階であり、本番環境での利用事例も限られています。状況的には、dbt Core v0.x時代のようにも感じられます。
(私がdbtをはじめて触ったのは2021年の夏頃でしたが、ユーザーコミュニティ(dbt Tokyo)はまだなく、セットアップの方法すらよく分からずハマり、随分と時間を溶かしました。dbt-osmosisのような便利なライブラリもなかったので、ほとんどのYAMLファイルを人力で書いていました。)
しかし、これらのツールはデータユーザーの利便性向上に繋がる可能性を秘めています。Gaudiyでは『New Standard』という行動指針に基づき、既存の価値観や事例を徹底的に分析し次の時代を見すえた新しい技術や方法論に挑戦しています。今回ご紹介した取り組みも、その一例です。
現在Gaudiyではこうした取り組みを一緒に推進してくれるデータアナリスト(アナリティクスエンジニア)、データエンジニアを募集しています。ご興味のある方はぜひ下記の採用情報をご覧ください。