0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

BigQueryだけでセマンティックレイヤができる?measures機能を使ってみた

0
Posted at

はじめに

AIエージェント時代において、「セマンティックレイヤ」の重要性が急速に高まっています。

ざっくり言うと、「revenue」や「churn」みたいな指標の定義を1箇所にまとめて、ダッシュボードでもAIエージェントでも同じ数字を使えるようにする仕組みのことです。
これが無いと、マーケティングと営業と財務でそれぞれ微妙に違う「売上」を計算してしまい、「なんで数字が合わないの?」と詰められる…というのはよくある話かもしれません。

そんな中、BigQueryにてmeasuresというセマンティックレイヤ系の新機能が追加されました。

本記事では、BigQueryだけでセマンティックレイヤを実現できるのか、実際に試してみた内容をまとめます。

本記事執筆時点(2026年8月)で、BigQuery GraphのMeasure機能はPreview機能になります。
GA時には仕様が変わる可能性があるため、最新情報は公式ドキュメントをご確認ください。

1. GCPのセマンティックレイヤ

Google Cloudでセマンティックレイヤの代表格といえば、Lookerが提供するLookMLです。
指標をLookMLで一度定義すれば、ダッシュボードでもAIエージェントからのクエリでも同じ定義が使われる、というのがLookerの強みです。

そんな中、2026年8月 BigQuery Graphに「measures」という機能が追加されたことが発表されました。

公式ブログでは

  • LookMLとmeasuresは相互運用できる
  • Looker側のsql_analytic_model_nameでBigQuery Graph上のmeasuresをそのまま参照できる

といった連携方法が説明されており、LookMLとBigQuery Graphが連動して指標を一元管理できる、という位置づけが示されていました。

BigQuery Graph自体は2026年4月にPreviewとして先行して発表されており、今回取り上げる「measures」機能はその後追加されたものになります。

2. BigQueryのmeasures機能とは

measuresは独立した機能ではなく、BigQuery Graphというグラフ機能のPreview機能の一部になります。

  • BigQuery Graphは、通常のテーブルを「ノード(実体)」「エッジ(関係性)」として捉え直し、CREATE PROPERTY GRAPH文でグラフとして定義できる機能
  • そのノード/エッジのPROPERTIES句の中で、MEASURE()という関数を使ってメトリクス(例:合計売上)を定義できる

公式ブログでは、churn rate(解約率)のような指標がダッシュボードとAIエージェントの両方で同じ値になることを保証する仕組みとして紹介されています。
フラットなテーブルに直接メトリクスを生やす、というよりは「グラフ機能のおまけ」に近い立ち位置、という印象です。

3. 【実践】シンプルなグラフでメジャーを定義

今回は、パブリックデータセット(bigquery-public-data.thelook_ecommerce)を使ってグラフの作成およびmeasureの定義を行ってみます。
このデータセットには、以下のような1対多の関係を持つテーブルがあります。

  • orders:1行=1つの注文(num_of_itemという「その注文に含まれる商品数」を持つ)
  • order_items:1行=1つの商品(1つの注文に対して複数行になりうる)

例えば、ある注文(order_id = 1)には商品が2つ(order_itemsが2行)含まれている、という具体例で考えてみます。

そもそもMEASUREがないとどうなるか

ordersorder_itemsを素朴にJOINすると、orders側のnum_of_itemが商品の行数だけ複製されてしまいます。

商品が2つある注文は、JOIN後に2行に増えます。
そのため単純にSUM(num_of_item)すると、本来「2」であるはずの商品数が「2 + 2 = 4」と、実際の2倍に集計されてしまうわけです。これがJOINによる「重複集計(オーバーカウント)」という問題です。

BigQueryのmeasures機能がGraph機能の一部として存在する理由の1つが、まさにこの問題への対処です。

「どのキー(今回はorder_id)を基準に、何を集計するか」をあらかじめMEASUREとして定義しておくことで、JOINで行が増えても重複せず正しく集計できる、という仕組みになっています。

BigQuery Graphを使用して合計値を出してみる

手順①:2テーブル構成のグラフを作成

CREATE OR REPLACE PROPERTY GRAPH `YOUR_PROJECT_ID.graph_demo.ecommerce_graph2`
NODE TABLES (
  `bigquery-public-data.thelook_ecommerce.orders` AS orders
    KEY (order_id)
    PROPERTIES (
      order_id,
      user_id,
      num_of_item,
      MEASURE(SUM(num_of_item)) AS total_num_of_item
    ),
  `bigquery-public-data.thelook_ecommerce.order_items` AS order_items
    KEY (id)
    PROPERTIES (
      id,
      order_id,
      sale_price,
      MEASURE(SUM(sale_price)) AS total_sales
    )
)
EDGE TABLES (
  `bigquery-public-data.thelook_ecommerce.order_items` AS OrderHasItem
    KEY (id)
    SOURCE KEY (order_id) REFERENCES orders (order_id)
    DESTINATION KEY (id) REFERENCES order_items (id)
    NO PROPERTIES
);

order_itemsテーブルを、ノード(商品そのもの)とエッジ(注文とのつながり)の両方として使っているのがポイントです。エッジとして使う場合もKEYの明示が必要でした。

実際作成されたグラフは以下のような形になります。

image.png

手順②:素朴なJOINで重複集計を再現する

まずMEASUREを使わず、普通にJOINSUMしてみます。

SELECT
  o.user_id,
  SUM(o.num_of_item) AS naive_total_items
FROM `bigquery-public-data.thelook_ecommerce.orders` o
JOIN `bigquery-public-data.thelook_ecommerce.order_items` oi
  ON o.order_id = oi.order_id
GROUP BY o.user_id
ORDER BY o.user_id ASC
LIMIT 10;

結果としては以下の通り。

image.png

手順③:MEASURE+AGGで正しく集計する

SELECT
  orders_user_id,
  AGG(orders_total_num_of_item) AS correct_total_items,
  AGG(order_items_total_sales) AS total_sales
FROM
  GRAPH_EXPAND("YOUR_PROJECT_ID.graph_demo.ecommerce_graph2")
GROUP BY orders_user_id
ORDER BY orders_user_id ASC
LIMIT 10;

measuresを使用した場合の結果は以下の通り。

image.png

値を比較してみる

同じuser_id(③ではorders_user_id)でnaive_total_itemscorrect_total_itemsを見比べると、手順②で作成されたnaive_total_itemsの方が大きい値になっているケースがあることが確認できました。

1つの注文に商品が複数あるユーザーほど、素朴なJOINでは商品数が重複してカウントされてしまい、実際より多く見えてしまっていたということです。

実際に手を動かしてみて分かったのは、BigQueryのmeasures機能の本質は「メトリクスを1箇所に定義する」ことそのものではなく、GraphのKEYを基準に、JOINしても重複集計されない形で値を取り出せるという集計方式にあった、という点でした。
ただし、これはLookMLのmeasureも同様に解決している問題です。

4. LookML・BigQuery それぞれの強み

実践だけでは見えてこない部分についても、公式ドキュメントを中心に機能面の違いを整理してみます。

観点 LookML(Looker) measures(BigQuery)
可視化・BI連携 ダッシュボード・Exploreと一体 データ層のみ、可視化は別途必要
モデリング対象 任意のテーブルを自由にJoin可能 Property Graph(ノード/エッジ)構造が前提
ガバナンス Git管理・アクセス制御が言語仕様に組み込み済み 別途IAM等で構築が必要
集計の正確性 measure型(symmetric aggregates)でJOINの重複集計を防止 GraphのKEYを基準にMEASUREAGG()でJOINの重複集計を防止(前セクションの実践で確認)
利用範囲 Looker経由が前提 BigQueryに直接つながる任意のツール・エージェントから参照可能

なお、「集計の正確性」はどちらも同じ問題(JOINの重複集計)への解決策であり、BigQueryのmeasures機能側だけの強みというわけではありません
それぞれ以下のように別アプローチで同じ問題を解決しています。

  • LookML:measure型のsymmetric aggregatesという仕組み
  • measures(BigQuery Graph):GraphのKEYを基準にした集計方式

なお、公式ブログでは「シアトルの売上減少の原因を、物流拠点→サプライヤー→悪天候とたどって推論する」といった多段階(multi-hop)の関係性推論も強みとして紹介されています。

可視化を含むBIツールとして使いたい → LookML
データ層で関係性推論・エージェント連携を重視したい → measures(BigQuery)
というのが住み分けの軸になりそうです。


まとめ

「BigQueryだけでLooker要らずのセマンティックレイヤーができるか」を試してみた結果、

  • measuresはBigQuery Graphの一部機能で、フラットテーブル単体では完結しない
  • JOINの重複集計を防ぐ仕組みはLookMLも同様に持っており、BigQuery側だけの強みとは言い切れない(multi-hopであればBigQueryが優位)
  • 可視化・ガバナンスまで含めた一式としてはLookMLが優位、データ層で完結する手軽さはBigQueryの強み

という結果になりました。
「Lookerの完全な代替」というよりは、用途によって使い分ける関係に近そうです。

BigQueryのmeasures機能自体はまだPreviewなので、GAされたタイミングで改めて追いかけたいと思いました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?