この
ブログシリーズでは、最近リリースされた
インタラクティブ Google 広告クエリビルダー ツールの構築過程についてお伝えしています。シリーズの
パート 1 では、このシリーズで説明する大まかな内容と、このコンテンツを公開することになった理由を紹介しました。パート 2 では、インタラクティブ クエリビルダー
Angular アプリケーションの正規データセットとして利用する詳細な JSON リソース スキーマの設計について取り上げます。
背景
パート 1 でも述べたように、新しいインタラクティブ クエリビルダーの大きなメリットの 1 つは、Google Ads Query Language(GAQL)クエリの句において、フィールドを選択できる理由やできない理由をリアルタイムで細かくフィードバックできることです。
たとえば、
ad_group
を FROM 句のメインリソースとする GAQL クエリを作成する場合を考えてみましょう。
ad_group
リソースでは、
segments.conversion_action
と
metrics.absolute_top_impression_percentage
の両方を選択できます。しかし、
segments.conversion_action
の詳しいリファレンス ドキュメントを見ると、一緒に選択できる("Selectable With")フィールドのリストが記載されており、そこには
metrics.absolute_top_impression_percentage
は含まれていません。そのため、この 2 つのフィールドを同時に使用することはできません。FROM 句のリソースが何であれ、クエリにこの 2 つのフィールドのどちらかが存在すれば、もう片方は使用できません。そのため、
segments.conversion_action
を選択すると、インタラクティブ クエリビルダーで
metrics.absolute_top_impression_percentage
は選択できなくなります。
私たちは、実行時にサーバーを何度も呼び出してすべてのロジックを知ろうとするよりも、リソース スキーマを含む静的な JSON ファイルをアプリケーションに渡す方が便利だと考えました。しかし、最適なスキーマとはどのようなものでしょうか。
スキーマの設計(定義はこのブログ投稿の最後に掲載)
GAQL 文字列では、FROM 句に 1 つのリソースが必要です。この制約を考えると、トップレベルの JSON スキーマは、リソースからそれぞれのリソースの詳細スキーマへのマップとなります。たとえば、スキーマの
ad_group
エントリは次のようになります。
{
"ad_group": {
"name": "ad_group",
"display_name": "Ad Group",
"description": "An ad group.",
// Array of all attribute and attributed resource fields.
"attributes": [
"ad_group.ad_rotation_mode",
"ad_group.base_ad_group",
"ad_group.campaign",
...
"campaign.ad_serving_optimization_status",
"campaign.advertising_channel_sub_type",
"campaign.advertising_channel_type",
...
"customer.auto_tagging_enabled",
"customer.call_reporting_setting.call_conversion_action",
"customer.call_reporting_setting.call_conversion_reporting_enabled",
...
],
// Array of all metrics selectable with ad_group.
"metrics": [...],
// Array of all segments selectable with ad_group.
"segments": [...],
// Expanded info for all items listed in attributes, metrics, and segments arrays.
"fields": {...}
}
この拡張スキーマの厄介な点は、
fields
エントリです。このオブジェクトのキーは、トップレベルのリソース(
ad_group
など)のすべての属性、指標、セグメントです。このオブジェクトのそれぞれの項目の値は、そのフィールドについての詳細情報と、
incompatible_fields
という追加フィールドを含むオブジェクトです。この追加フィールドは、そのフィールドと同時に選択できないフィールドの配列です。たとえば、
fields
オブジェクトの
metrics.phone_impressions
エントリは次のようになります。
"metrics.phone_impressions": {
"field_details": {
"name": "metrics.phone_impressions",
"category": "METRIC",
"selectable": true,
"filterable": true,
"sortable": true,
"data_type": "INT64",
"is_repeated": false,
"type_url": "",
"description": "Number of offline phone impressions.",
"enum_values": [],
"selectable_with": [
"ad_group",
"ad_group_ad",
"campaign",
"customer",
"extension_feed_item",
"segments.ad_network_type",
"segments.click_type",
"segments.date",
"segments.day_of_week",
"segments.interaction_on_this_extension",
"segments.keyword.ad_group_criterion",
"segments.keyword.info.match_type",
"segments.keyword.info.text",
"segments.month",
"segments.month_of_year",
"segments.quarter",
"segments.week",
"segments.year"
]
},
"incompatible_fields": [
"segments.slot",
"segments.device",
"segments.external_conversion_source",
"segments.conversion_action_category",
"segments.conversion_lag_bucket",
"segments.hour",
"segments.conversion_action_name",
"segments.conversion_action",
"segments.conversion_adjustment",
"segments.conversion_or_adjustment_lag_bucket"
]
},
このスキーマは再帰的で、一部のフィールドは複数のリソースに登場するので、冗長に思えるかもしれません。しかし、読み込み時間を減らすため、最終的にはこのメインスキーマを分割してそれぞれのリソースを表す JSON ファイルを作成し、FROM 句のリソースに応じてリソースに固有な 1 つのスキーマのみを取得します。
スキーマ定義
参考までに、完全なスキーマ定義を示します。
interface ResourceSchema {
name: string; // the name of the resource
display_name: string; // the display name of the resource
description: string; // the description of the resource
attributes: string[]; // the resource's fields (including attributed resource fields)
metrics: string[]; // available metrics when the resource is in the FROM clause
segments: string[]; // available segments when the resource is in the FROM clause
fields: { // detailed info about all fields, metrics, and segments
[key: string]: {
field_details: FieldDetails; // details about the field (defined below)
incompatible_fields: string[]; // fields that are incompatible with the current field
}
};
}
interface FieldDetails {
name: string; // the name of the field
category: string; // the field's category (e.g. ATTRIBUTE, METRIC, SEGMENT)
selectable: boolean; // whether or not the field is allowed to be placed in the SELECT clause
filterable: boolean; // whether or not the field is allowed to be placed in the WHERE clause
sortable: boolean; // whether or not the field is allowed to be placed in the ORDER BY clause
data_type: string; // the field's data type
is_repeated: boolean; // whether or not the field is a repeated field
type_url: string; // the field's type_url
description: string; // the field's description
enum_values: string[]; // possible enum values if the field is of type ENUM
selectable_with: string[]; // the list of field the current field is selectable with
}
まとめ
以上で、詳細なフィールド情報と、それぞれのフィールドと同時に選択できないフィールドのリストを含む拡張リソース スキーマが設計できました。Angular アプリケーションでは、このスキーマを利用します。パート 3 では、
GoogleAdsFieldService
を使ってこのスキーマを作成する方法について説明します。