1. はじめに
Lost Cargo 調査の最終段階へようこそ!ロンドンからシドニーまで追跡してきた Android フィギュアの盗難コンテナの追跡が途絶えてしまいました。コンテナのスマート セキュリティ ボルトのトランスポンダーが無効化されたため、自動的な緊急ロックダウンがトリガーされました。
貴重な貨物が永久にロックされる前に回収するため、コンテナの最終位置を特定し、手動オーバーライドのパスコードを取得して、金庫を物理的に開けることがミッションとなります。

紛失したコンテナを見つけて貨物を保護するには、BigQuery プロパティ グラフを構築して、荷物の配送経路を追跡します。次に、会話型分析を使用してこのネットワークを自然言語でクエリし、最後に Knowledge Catalog を使用してデータのメタデータに対するセマンティック検索を実行し、オーバーライド コードを見つけます。
💡 ラボ 1またはラボ 2を見逃しましたか?ご安心ください。このラボは完全に自己完結型です。環境設定の手順では、必要なものがすべてプロビジョニングされるため、すぐに開始して単独で完了できます。
演習内容
- リポジトリのクローンを作成し、Google Cloud Shell で設定スクリプトを実行します。
- BigQuery で、会社、船舶、マニフェストのデータをリンクするプロパティ グラフを構築します。
- 会話分析を使用すると、自然言語でグラフにクエリを実行し、貨物の輸送経路を追跡して、担当の運送業者を特定できます。
- Knowledge Catalog を使用して、最終的なオーバーライド コードを保持するテーブルを見つけます。
- BigQuery の列レベルのアクセス制御を使用して、最終的なコードをマスク解除して表示します。
必要なもの
- ウェブブラウザ(Chrome など)
- 課金を有効にした Google Cloud プロジェクト
- Google Cloud Shell へのアクセス
この Codelab は、あらゆるレベルのデータ実務者を対象としています。
この Codelab で作成するリソースの費用は 5 ドル未満です。
推定所要時間: この Codelab の所要時間は約 45 分です。
2. 始める前に
Google Cloud プロジェクトの作成
- Google Cloud コンソールのプロジェクト セレクタ ページで、Google Cloud プロジェクトを選択または作成します。
- Cloud プロジェクトで課金が有効になっていることを確認します。
Cloud Shell の起動
Google Cloud Shell を使用して、コードのダウンロード、設定スクリプトの実行、アプリケーションのデプロイを行います。
- 新しいブラウザタブで、Cloud Shell を開きます。

- 接続したら、プロジェクト ID を設定して環境を確認します。
gcloud config set project <<YOUR_PROJECT_ID>>
export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
次のようなメッセージが表示されます。
Your active configuration is: [cloudshell-####] Updated property [core/project]
必要な API の有効化
Cloud Shell で次のコマンドを実行して、必要な API を有効にします。
gcloud services enable \
bigquery.googleapis.com \
aiplatform.googleapis.com \
datacatalog.googleapis.com \
geminidataanalytics.googleapis.com \
cloudaicompanion.googleapis.com
実行が成功すると、次のようなメッセージが表示されます。
Operation "operations/..." finished successfully.
3. 環境をセットアップする
このシリーズの前のラボでは、調査の基礎を築きました。
1. リポジトリのクローンを作成する
Cloud Shell 環境に Codelab リポジトリのクローンを作成します。
cd ~/
git clone --filter=blob:none --no-checkout https://github.com/GoogleCloudPlatform/devrel-demos.git
cd ~/devrel-demos
git sparse-checkout init --cone
git sparse-checkout set codelabs/bigquery-graph-analytics
git checkout main
cd codelabs/bigquery-graph-analytics/
2. ベーステーブルとポリシータグを設定する
設定スクリプトを実行して BigQuery データセットにデータを入力し、列レベルのセキュリティ タグを適用してセンシティブ データを制限します。
bash setup_lab.sh
ターミナルの出力に初期化が成功したことが表示されていることを確認します。
🚀 Provisioning foundational tables and deploying Policy Tag security bindings... 🎯 Active Project: your-project-id ... 🎉 Success! Foundational tables initialized and Column-Level Policy Tags fully mapped out of the box!
環境が正常に設定され、ロジスティクス データが BigQuery に入力されたので、テーブルを接続して貨物の移動を追跡するプロパティ グラフを構築できます。
4. BigQuery Graph を使用してデータを接続する
サプライ チェーンのデータを分析するために、企業、船舶、マニフェストが互いにどのように関連しているかを定義します。プロパティ グラフを構築すると、これらの接続を簡単にクエリできます。
1. プロパティ グラフによる関係のモデル化

BigQuery プロパティ グラフは、次のものを使用してネットワークをモデル化します。
- ノード: ネットワーク内のエンティティ。このラボでは、ノードは企業(連絡先情報を直接保存)、マニフェスト、船舶を表します。
- エッジ: ノードをリンクする関係。例:
- エッジは、マニフェストをベッセルに接続します(
manifestsテーブルのリレーションを介して)。 - エッジは、Vessel を Company に接続します(
vesselsテーブルのリレーションを介して)。
- エッジは、マニフェストをベッセルに接続します(
- プロパティ: ノードまたはエッジに保存されるメタデータ。たとえば、Company ノードには
company_nameやphone_numberなどの列があり、Manifest ノードにはseal_integrity_statusと座標(last_ping_lat、last_ping_long)があります。 - ラベル: クエリツールがノードと関係のタイプを認識できるように、ノード(
Company、Vessel、Manifestなど)とエッジ(CARRIED_BY、OPERATED_BYなど)に割り当てられたタグ名。
2. BigQuery にプロパティ グラフをデプロイする
setup_graph.sql ファイルには、プロパティ グラフを定義して作成する SQL DDL が含まれていますが、現在は未完成です。このスキーマ ファイルでエッジラベル(関係)を定義してから、コンパイルしてデプロイする必要があります。
- Cloud Shell エディタを開きます。

- Cloud Shell エディタで
setup_graph.sqlファイルを開きます。

- エッジラベルのプレースホルダを見つけます。
- 22 行目:
`EDGE_TABLE_PLACEHOLDER`を、マニフェストと船舶の関係を表す意味のあるタグ(CARRIED_BYなど)に置き換えます。 - 27 行目:
`EDGE_TABLE_PLACEHOLDER`は、船舶と企業の関連性を示すタグ(OPERATED_BYなど)に置き換えます。
- 22 行目:
- ファイルを保存します。
Cloud Shell ターミナルに戻り、完成したスクリプトを使用して更新されたプロパティ グラフをデプロイします。
bq query --use_legacy_sql=false < setup_graph.sql
ジョブが完了したことを示す出力が表示されます。
Waiting on bqjob_r... ... (0s) Current status: DONE
プロパティ グラフの詳細は、BigQuery コンソールで確認できます。
lost_cargo_dataset を見つけて、[グラフ] を選択します。

プロパティ グラフが正常にコンパイルされたので、BigQuery Studio で接続をクエリして可視化してみましょう。
5. グラフのクエリを実行する
BigQuery Studio 内で、ネイティブの Graph Query Language(GQL)を使用してグラフをクエリし、視覚的に探索できます。
1. コンテナ -> 船舶 -> 会社のチェーンをクエリする
貨物を運ぶ船舶を運航している会社を特定して、GQL クエリについて見ていきましょう。運送業者を見つけるには、物流ネットワーク内の 3 つの異なるエンティティ ノードを横断する必要があります。

- コンテナ
Manifestノードから開始します。 CARRIED_BY関係エッジをたどって、実行中のVesselを見つけます。- その船舶から担当の
CompanyへのOPERATED_BY関係エッジをたどり、その ID を取得します。
まず、クエリを実行して、ネットワーク全体を(フィルタなしで)可視化し、グラフ全体を表示します。
- BigQuery Studio SQL エディタで新しいタブを開き、次の GQL クエリを貼り付けて、[実行] をクリックします。
SELECT * FROM GRAPH_TABLE( `lost_cargo_dataset.logistics_network` MATCH p = (m:Manifest)-[:CARRIED_BY]->(v:Vessel)-[:OPERATED_BY]->(comp:Company) RETURN TO_JSON(p) AS path ); - クエリが完了したら、下部の [クエリ結果] ペインで [グラフ] タブ([結果テーブル] タブの横)をクリックします。

- BigQuery は、結果をインタラクティブな視覚グラフ表現としてレンダリングします。ズームインすると、接続されたコンテナ、船舶、運送業者のネットワーク全体が表示されます。
GQL クエリの構造
先ほど実行した GQL クエリを分解してみましょう。
GRAPH_TABLE:logistics_networkグラフに対してプロパティ グラフ クエリを実行するように BigQuery に指示します。MATCH: マルチホップ トラバーサル パターンを宣言します。Manifest(m)から開始し、Vessel(v)を指すエッジ関係:CARRIED_BYを照合し、Company(comp)を指すエッジ関係:OPERATED_BYを照合します。- GQL は、複雑な結合ロジックを直感的で人間が読める ASCII アートの関係矢印
()->[]->()に置き換えるため、マルチホップ クエリの作成と最適化が非常に簡単になります。 RETURN: 一致する要素からプロパティまたは JSON パスを返します。
2. GQL クエリの結果をフィルタする
次に、クエリをフィルタして、ターゲットの侵害されたコンテナ MV-CAPYBARA-003 のパスのみを表示します。
- 次のクエリを SQL エディタに貼り付けて、[実行] をクリックします。
SELECT * FROM GRAPH_TABLE( `lost_cargo_dataset.logistics_network` MATCH p = (m:Manifest {shipment_id: 'MV-CAPYBARA-003'})-[:CARRIED_BY]->(v:Vessel)-[:OPERATED_BY]->(comp:Company) RETURN TO_JSON(p) AS path ); - 結果の [グラフ] タブをクリックします。

- ビューアには、
MV-CAPYBARA-003のアクティブなトラバーサル ルートのみが表示されるようになりました。ノードと接続を表示するには、ズームインします。Companyノードをダブルクリックして、プロパティ パネルを開きます。[プロパティ] に、演算子company_id:103(Davy Jones Shipping)が表示されます。この会社 ID をメモしておきます。後でセキュリティ レジストリから通関パスコードを取得する際に必要になります。Vesselノードをダブルクリックして、Flying Dutchmanであることを確認します。
6. 会話型分析を使用してグラフとチャットする
グラフを手動でクエリして会社 ID を見つけたので、今度は会話型分析を使用してグラフに直接話しかけ、コンテナの行き先を特定してみましょう。
1. Conversational Analytics セッションを開始する
- Google Cloud コンソールで BigQuery コンソールに移動し、リソース パネルを開いてデータセット(
lost_cargo_dataset)を見つけます。 - プロパティ グラフ リソース
logistics_networkをクリックします。 - 上部の詳細パネルのツールバーで、[チャット] ボタンをクリックします。グラフのコンテキストが事前読み込みされた会話型分析セッションが開きます。

2. ハイジャックされたコンテナの最寄りのドッキング ポートを特定する
海上哨戒機が、貨物船の説明と一致する船舶が座標 POINT(-122.48 37.55) でオフグリッド(トランスポンダーが無効)で航行しているのを発見しました。貨物を奪取するには、シャドー シンジケート Davy Jones Shipping が活動している最寄りのドッキング ポートを見つける必要があります。
すべてのグローバル ポートを手動で検索する代わりに、グラフ ネットワークにクエリを実行して、シンジケートのアクティブなフリートに接続されているポートを取得し、目撃情報に物理的に最も近いポートを測定します。
- [会話型分析] のチャット ボックスに次のプロンプトを入力します。
Find all ports associated with Davy Jones Shipping vessels. Which port is closest to coordinate POINT(-122.48 37.55), show the distance in km, and display it on a map.

- 回答をよく確認します。エージェントはグラフをトラバースし、最も近いドッキング施設とその距離を返します。
- ドッキング ポート:
Mountain View Terminal - 距離:
39.42 kilometers
- ドッキング ポート:
- 会話型分析は、ネイティブの地理空間(GIS)統合を備えた Gemini を搭載しているため、地理座標点を解釈し、世界に関する知識を活用して位置情報を確認できます。「船はカリフォルニア州マウンテン ビュー ターミナルから約 39.42 キロメートルの地点にあり、ドッキングのためにそこに向かっていることを示しています。」
これで、荷物がマウンテンビューに直接向かっていることが確認できました。
内部: Graph Query Language(GQL)と地理空間 GIS
バックグラウンドでは、会話型分析エージェントが、グラフのパス照合と地理空間距離の計算を組み合わせたクエリを動的にコンパイルして実行しました。これは、ネイティブの GQL COLUMNS 句を使用して実現され、グラフ トラバーサル マッチ内で測地線距離をネイティブに計算します。
SELECT port_id, port_name, country, latitude, longitude, distance_km
FROM GRAPH_TABLE(
`lost_cargo_dataset.logistics_network`
MATCH (c:Company)<-[]-(v:Vessel)-[]->(p:Port)
WHERE LOWER(c.company_name) = 'davy jones shipping'
COLUMNS (
p.port_id,
p.port_name,
p.country,
p.latitude,
p.longitude,
ROUND(ST_DISTANCE(ST_GEOGPOINT(p.longitude, p.latitude), ST_GEOGPOINT(-122.48, 37.55)) / 1000, 2) AS distance_km
)
)
ORDER BY distance_km ASC;
ネイティブの地理空間(GIS)関数(ST_DISTANCE、ST_GEOGPOINT)と GQL プロパティ グラフ一致を組み合わせることで、BigQuery はシンジケートの運用フットプリントを動的に解決し、現実世界の物理的な近接性を 1 つのクエリで計算します。
7. Knowledge Catalog で欠落しているデータを見つける
プロパティ グラフには関係が表示されますが、実際のオーバーライド コードが保存されているテーブルは含まれていません。
数百ものデータセットとテーブルが存在する実際のエンタープライズ環境では、この情報を見つけるのは困難です。ナレッジ カタログを使用してセマンティック検索を実行し、正しいテーブルを見つけます。
1. Knowledge Catalog のセマンティック検索
- Google Cloud コンソールで、[Knowledge Catalog] ➔ [検索] を検索して移動します。
- [システム] の検索フィルタ列で、[BigQuery] をオンにして結果を絞り込みます。
- 検索ボックスに次のクエリを入力します。
container override codes

- 検索結果に表示された
maritime_security_registryテーブル リソースをクリックします。
メタデータ スキーマを調べると、このテーブルにはコンテナ セキュリティ データ(コーディネーター会社 co_id、カストディアン トークン cust_tok、最も重要なセキュア コンテナのオーバーライド パスコード列 clc_ovr_cd など)の列が含まれていることがわかります。
テーブルと、貨物を取り戻すために必要な正確な安全な列の両方を特定できました。
🔓 実際のガバナンス: 本番環境のエンタープライズ環境では、セキュリティ チームとガバナンス チームは次のものも活用します。
- アスペクトとタグ テンプレート: ビジネス メタデータ(データ オーナー、保持期間、PII 分類など)をテーブル スキーマに付加します。
- データ リネージ:
maritime_security_registryなどのテーブルがダウンストリーム システムによってどのようにクエリされ、使用されるかを表すフローチャートを自動生成します。
2. BigQuery で列のセキュリティを検査する
- BigQuery コンソールに戻ります。
- [エクスプローラ] タブで、
lost_cargo_datasetを選択し、maritime_security_registryテーブルをクリックします。 - [スキーマ] タブをクリックします。

clc_ovr_cd列がMaskShippingDetailsという名前のポリシータグによって保護されていることに注目してください([ポリシータグ] 列に表示されています)。- BigQuery で新しい SQL エディタタブを開き、次のクエリを実行してレジストリ オーバーライド コードを表示します。
SELECT * FROM `lost_cargo_dataset.maritime_security_registry` WHERE co_id = 103; - アカウントに
MaskShippingDetailsでタグ付けされた列を読み取る権限がないため、クエリはすぐに失敗し、アクセス拒否のデータベース セキュリティ エラーが発生します。

8. 列のセキュリティを破ってパスコードを取得する
最終的なオーバーライド コードをクリアテキストで読み取るには、MaskShippingDetails でタグ付けされた列を読み取る権限をユーザー アカウントに付与する必要があります。
1. ポリシータグの権限を付与する
- BigQuery コンソールの左側のナビゲーション パネルで、[ポリシータグ] に移動します。
LostCargoSecurity_という名前の分類を選択します。- タグのリストで、
MaskShippingDetailsをクリックします。 - 画面の右側の情報パネルで、[プリンシパルを追加] をクリックします。(パネルが表示されていない場合は、右上にある [情報パネルを表示] をクリックします)。
- [新しいプリンシパル] フィールドに、アクティブな Google Cloud ユーザーのメールアドレスを入力します。
- [ロールを選択] プルダウンで、[きめ細かい閲覧者] を検索して選択し、[保存] をクリックします。

2. オーバーライド コードのクエリ
BigQuery ワークスペース エディタに戻ります。きめ細かい読み取りアクセス権が付与されたため、クエリを再度実行して、マスクされていないデータを表示できるようになります。
SELECT * FROM `lost_cargo_dataset.maritime_security_registry`
WHERE co_id = 103;
🔓 結果
クエリは、マスクされていないオーバーライド コードを返します。
SHIVER-ME-TIMBERS-888

9. クリーンアップ
課金されないようにするには、このラボで作成したサンドボックス リソースをクリーンアップします。
Cloud Shell ターミナルに戻り、ロジスティクス テーブルを含む BigQuery データセットを削除します。
bq rm -r -f -d lost_cargo_dataset
クローンされたリポジトリ ファイルを削除します。
cd ..
rm -rf data-cloud-roadshow-26
10. 完了
調査を完了し、クリアランスのオーバーライド コードを取得できました。
学習した内容
- BigQuery でプロパティ グラフを構築して、複雑なエンティティと関係を表す方法。
- データ接続をキャプチャするように ノード、エッジ、プロパティ、ラベルを構成する方法。
- BigQuery の会話型分析を使用して、自然言語でプロパティ グラフをクエリする方法。
- リレーショナル パスをトラバースするように Graph Query Language(GQL)式を構成する方法。
- Knowledge Catalog を使用して保護されたアセットを検出し、ポリシータグを使用して列レベルで制限されたデータにアクセスする方法。