プレミアムGoogleAnalyticsアカウントがあり、行レベルのイベントデータにアクセスできます。このデータは毎日GoogleBigqueryにエクスポートされ、毎日新しいテーブルがデータセットに作成されます。
1週間前までは、このGoogle Analyticsデータを一時ステージングテーブルにフラット化してからCSVにエクスポートすることで、このデータをCSVにエクスポートすることができました。以前使用したクエリは次のようになりました。
SELECT * FROM
flatten([xxxxxxxx.ga_sessions_20140829],hits),
flatten([xxxxxxxx.ga_sessions_20140828],hits),
flatten([xxxxxxxx.ga_sessions_20140827],hits),
flatten([xxxxxxxx.ga_sessions_20140826],hits)
昨日、このクエリがエラーをスローすることに気づきました。
Cannot output multiple independently repeated fields at the same time. Found customDimensions_value and hits_product_productSKU
Hits_product_productSKUはhitsフィールドの子であるため、flatten()関数に関して何かが変更されたようです。
クエリ履歴にある古いクエリもいくつか試しましたが、それらも壊れています。変更について言及しているリリースノートはありませんが、何が起こっているのでしょうか。
Google Analytics BigQueryエクスポートファイルのすべてを再度エクスポートするにはどうすればよいですか?
これは実際には先週提出したバグ修正の結果であり、誤った結果が得られるのを防いでいます。
BigQueryはデフォルトで、すべてのクエリ結果を返す前にフラット化しますが、データの外積展開を避けるために、独立して繰り返される1つのフィールドのみをフラット化します。バグは、複数の繰り返しフィールドのチェックで親レコードの繰り返しを考慮に入れられなかったため、いくつかの独立して繰り返されたフィールドをフラット化できなかったことです。これは、実際には間違った結果である外積を生成する代わりに、独立して繰り返される値が実際に依存して繰り返される値に「フラット化」されたフラット行を返すことができることを意味しました。
ここに表示されているのは、より厳密なチェックの結果です。結果をフラット化しようとする前に、出力スキーマに(少なくとも)2つの繰り返しフィールドがあります。
注意すべきもう1つの重要な点は、FLATTEN([table-value]、[field])関数は、2番目の引数として指定したフィールドの繰り返しを平坦化するだけであるということです。 flatten([xxxxxxxx.ga_sessions_20140829]、hits)と言うと、「ヒット」レコードのみがフラット化されます。繰り返される子(製品、プロモーションなど)もフラット化する場合は、次のように、これらのフィールドに別のフラット化を明示的に追加する必要があります。
FLATTEN(FLATTEN([xxxxxxxx.ga_sessions_20140829]、hits)、hits.product)
-
サンプルを機能させるには、いくつかのオプションがあります。
1)選択するフィールドの数を減らします。いくつかのフィールドのフラット化された出力のみを取得することに関心がある場合は、関心のあるフィールドのみを明示的に選択することで、クエリ結果から個別に繰り返されるフィールドを削除できます。
2)さらにFLATTENを追加します。繰り返される各フィールドをフラット化する必要があります。これには、少なくともhits、hits.product、およびcustomDimensionsが含まれているように見えます。エラーメッセージがさまざまな繰り返しフィールドについて文句を言う場合があります。スキーマの繰り返しフィールドに、機能するまでFLATTENを追加します。
BigQuery Webコンソールを使用している場合は、宛先テーブルを選択し、大きな結果を許可をクリックして、フラットな結果のチェックを外します。
Bqコマンドラインツールを使用している場合:
bq query --allow_large_results --noflatten --destination_table NAME_OF_TABLE "SELECT * from FLATTEN( [dataset], hits)"
GAデータをリレーショナルデータベースにインポートしたい場合:ネストされたスキーマは実際には複数のリレーショナルテーブルを1つのネストされた構造に配置していることに注意してください-それらは同等であるため、単純なフラット化はここでの最善の解決策:テーブルを再び分離したい!そうすれば、多くのスペースを節約できますストレージ内にあると、クエリが速くなる可能性があります。
GAデータは3つのリレーショナルテーブルであると考えることができます:
セッションテーブルを取得するには、次のようなものを使用できます
-- session table
SELECT
* EXCEPT(hits,
customDimensions),
CONCAT('{',(
SELECT
STRING_AGG(CONCAT(CAST(index AS string),':"',value,'"') )
FROM
t.customdimensions),'}') as customDimensions
FROM
`project.dataset.ga_sessions_20171031` AS t
customDimensionsはjson文字列に集約されます。
ヒットテーブルと同様に:
-- hits table
SELECT
fullvisitorid,
visitid,
visitstarttime,
h.* EXCEPT(product,
customdimensions, customMetrics, customVariables, promotion, experiment),
CONCAT('{',(
SELECT
STRING_AGG(CONCAT(CAST(index AS string),':"',value,'"') )
FROM
h.customdimensions),'}') AS hitsCustomDimensions,
CONCAT('{',(
SELECT STRING_AGG(CONCAT(CAST(index AS string),':',cast(value as string)) )
FROM h.custommetrics),'}') AS hitsCustomMetrics
FROM
`project.dataset.ga_sessions_20171031` AS t,
t.hits AS h
副選択を使用してcustomDimensionsで行ったように、プロモーションと実験を追加できます。
Fullvisitorid + visitstarttime/visitidの連結を使用してヒットのあるセッションに参加します(GAセッションには深夜の分割が含まれます:visitidの代わりにvisitStartTimeを使用してください!深夜の分割を無視したい場合はvisitidを使用してください-分割しても同じままです)
製品の場合、ヒット番号を「セッションID」に追加して、一意の識別子を取得します。
-- product table
SELECT
fullvisitorid,
visitid,
visitstarttime,
h.hitNumber,
p.* EXCEPT(customdimensions, customMetrics),
CONCAT('{',(
SELECT STRING_AGG(CONCAT(CAST(index AS string),':"',value,'"') )
FROM p.customdimensions),'}') AS productsCustomDimensions,
CONCAT('{',(
SELECT STRING_AGG(CONCAT(CAST(index AS string),':',cast(value as string)) )
FROM p.custommetrics),'}') AS productsCustomMetrics
FROM
`project.dataset.ga_sessions_20171031` AS t,
t.hits AS h, h.product as p
これで、任意のリレーショナルデータベースで必要に応じて結合できる3つのリレーショナル/「フラット」テーブルができました。
Google Analytics Premiumによって生成されたテーブルは、新しい列が追加されて拡張されたと思います。クエリで*セレクターが使用されていて、新しい列の1つにネストされた値が含まれている場合を除いて、列の追加は問題になりません。
推奨される解決策:*を使用する代わりに、必要な列を明示的に要求します。
接続する前に、クエリをフラット化する必要があります。エラーに記載されているフィールドを選択し、ネストされたフラット化を使用するだけです。
SELECT * FROM
flatten(flatten(flatten([xxxxxxxx.ga_sessions_20140829],hits),customDimensions_value),hits_product_productSKU),
flatten(flatten(flatten([xxxxxxxx.ga_sessions_20140828],hits),customDimensions_value),hits_product_productSKU),
flatten(flatten(flatten([xxxxxxxx.ga_sessions_20140827],hits),customDimensions_value),hits_product_productSKU), flatten(flatten(flatten([xxxxxxxx.ga_sessions_20140826],hits),customDimensions_value),hits_product_productSKU)