Ruby クライアントを使用して Google Analytics Data API (GA4) のリストにフィルター式を追加するにはどうすればよいですか?
概要
Ruby クライアントで GA4 API をクエリするために google-analytics-data gem を使用しています。
フィルター式の配列をフィルター式リストに追加しようとすると、161 行目でエラーが発生します。
analytics_request_object_filter_expression_list.expressions = analytics_request_object_filter_expression_list_expressions
method_missing': Expected repeated field array
これが私のコードです
#! /usr/bin/ruby
require 'google-analytics-data'
module GoogleAnalyticsObjects
def self.get_analytics_data( analytics:,
start_date:,
end_date:,
metrics:,
dimensions:,
order_bys: [] )
analytics_date_range_object = Google::Analytics::Data::V1beta::DateRange.new
analytics_date_range_object.start_date = start_date
analytics_date_range_object.end_date = end_date
report_request_object_metrics = []
metrics.each { |metric|
analytics_metric_object = Google::Analytics::Data::V1beta::Metric.new
analytics_metric_object.name = metric
report_request_object_metrics.push(analytics_metric_object) }
unless dimensions.empty?
report_request_object_dimensions = []
dimensions.each { |dimension|
analytics_dimension_object = Google::Analytics::Data::V1beta::Dimension.new
analytics_dimension_object.name = dimension
report_request_object_dimensions.push(analytics_dimension_object) }
end
unless order_bys.empty?
report_request_object_order_bys = []
order_bys.each { |orderby|
analytics_orderby_object = Google::Analytics::Data::V1beta::OrderBy.new
analytics_orderby_object.field_name = orderby
analytics_orderby_object.sort_order = 'DESCENDING'
report_request_object_order_bys.push(analytics_orderby_object)}
end
################
analytics_request_object_filter_expression = Google::Analytics::Data::V1beta::FilterExpression.new
################
################
analytics_request_object_filter_expression_campaign = Google::Analytics::Data::V1beta::FilterExpression.new
################
################
analytics_request_object_filter_campaign = Google::Analytics::Data::V1beta::Filter.new
analytics_request_object_filter_campaign.field_name = 'campaign'
analytics_request_object_filter_campaign_string_filter = Google::Analytics::Data::V1beta::Filter::StringFilter.new
analytics_request_object_filter_campaign_string_filter.case_sensitive = false
analytics_request_object_filter_campaign_string_filter.value = '(not set)'
analytics_request_object_filter_campaign_string_filter.match_type = 'EXACT'
analytics_request_object_filter_campaign.string_filter = analytics_request_object_filter_campaign_string_filter
analytics_request_object_filter_expression_campaign.filter = analytics_request_object_filter_campaign # this filter expression gets added to the top level filter expression
puts
puts 'not expression filter expression'
puts analytics_request_object_filter_expression_campaign.inspect
###############
###############
analytics_request_object_filter_expression.not_expression = analytics_request_object_filter_expression_campaign # here
###############
puts
puts 'top level filter expression after not expression added'
puts analytics_request_object_filter_expression.inspect
###############
analytics_request_object_filter_expression_list = Google::Analytics::Data::V1beta::FilterExpressionList.new # gets added to the top level filter expression list
###############
###############
analytics_request_object_filter_expression_list_expressions = [] # array to hold top level filter expression and group filter expressions
###############
###############
analytics_request_object_filter_expression_source_medium = Google::Analytics::Data::V1beta::FilterExpression.new
analytics_request_object_filter_source_medium = Google::Analytics::Data::V1beta::Filter.new
analytics_request_object_filter_source_medium.field_name = 'sourceMedium'
analytics_request_object_filter_source_medium_string_filter = Google::Analytics::Data::V1beta::Filter::StringFilter.new
analytics_request_object_filter_source_medium_string_filter.case_sensitive = false
analytics_request_object_filter_source_medium_string_filter.match_type = 'EXACT'
analytics_request_object_filter_source_medium_string_filter.value = 'aomestring'
analytics_request_object_filter_source_medium.string_filter = analytics_request_object_filter_source_medium_string_filter
analytics_request_object_filter_expression_source_medium.filter = analytics_request_object_filter_source_medium
puts
puts 'sourceMedium filter expression'
puts analytics_request_object_filter_expression_source_medium.inspect
##############
##############
analytics_request_object_filter_expression_list_expressions.push(analytics_request_object_filter_expression_source_medium) # add to array
##############
##############
analytics_request_object_filter_expression_transactions = Google::Analytics::Data::V1beta::FilterExpression.new
analytics_request_object_filter_transactions = Google::Analytics::Data::V1beta::Filter.new
analytics_request_object_filter_transactions.field_name = 'transactions'
analytics_request_object_filter_transactions_numeric_filter = Google::Analytics::Data::V1beta::Filter::NumericFilter.new
analytics_request_object_filter_transactions_numeric_filter.operation = 'GREATER_THAN'
analytics_request_object_filter_transactions_numeric_value = Google::Analytics::Data::V1beta::NumericValue.new
analytics_request_object_filter_transactions_numeric_value.int64_value = 0
analytics_request_object_filter_transactions_numeric_filter.value = analytics_request_object_filter_transactions_numeric_value
analytics_request_object_filter_transactions.numeric_filter = analytics_request_object_filter_transactions_numeric_filter
analytics_request_object_filter_expression_transactions.filter = analytics_request_object_filter_transactions
puts
puts 'transactions filter expression'
puts analytics_request_object_filter_expression_transactions.inspect
#############
#############
analytics_request_object_filter_expression_list_expressions.push(analytics_request_object_filter_expression_transactions) # add to array
#############
puts
puts 'array of and group expressions'
puts analytics_request_object_filter_expression_list_expressions.inspect
#############
analytics_request_object_filter_expression_list.expressions = analytics_request_object_filter_expression_list_expressions
puts
puts 'and group expressions list final'
puts analytics_request_object_filter_expression_list.inspect
#############
#############
#analytics_request_object_filter_expression.and_group = analytics_request_object_filter_expression_and_group
analytics_request_object_filter_expression.and_group = analytics_request_object_filter_expressions_list
puts
puts 'top level filter expression'
puts analytics_request_object_filter_expression.inspect
#############
report_request_object = Google::Analytics::Data::V1beta::RunReportRequest.new(
property: "properties/#{ANALYTICS_PROPERTY_ID}",
metrics: report_request_object_metrics,
dimensions: report_request_object_dimensions,
order_bys: report_request_object_order_bys,
date_ranges: [analytics_date_range_object],
dimension_filter: analytics_request_object_filter_expression)
response = analytics.run_report(report_request_object)
end
end # module
編集。これは上記のコードからの出力です
not expression filter expression. This filter expression attaches to the not expression of the top level filter expression
<Google::Analytics::Data::V1beta::FilterExpression:
filter: <Google::Analytics::Data::V1beta::Filter:
field_name: "campaign",
string_filter: <Google::Analytics::Data::V1beta::Filter::StringFilter:
match_type: :EXACT,
value: "(not set)",
case_sensitive: false>>>
top level filter expression after not expression added
<Google::Analytics::Data::V1beta::FilterExpression:
not_expression:
<Google::Analytics::Data::V1beta::FilterExpression:
filter: <Google::Analytics::Data::V1beta::Filter:
field_name: "campaign",
string_filter: <Google::Analytics::Data::V1beta::Filter::StringFilter:
match_type: :EXACT,
value: "(not set)",
case_sensitive: false>>>>
Above is a singleton filter expression.
sourceMedium filter expression. First element of the and group
<Google::Analytics::Data::V1beta::FilterExpression:
filter: <Google::Analytics::Data::V1beta::Filter:
field_name: "sourceMedium",
string_filter: <Google::Analytics::Data::V1beta::Filter::StringFilter:
match_type: :EXACT,
value: "somestring",
case_sensitive: false>>>
transactions filter expression. Second element of the and group
<Google::Analytics::Data::V1beta::FilterExpression:
filter: <Google::Analytics::Data::V1beta::Filter:
field_name: "transactions",
numeric_filter: <Google::Analytics::Data::V1beta::Filter::NumericFilter:
operation: :GREATER_THAN,
value: <Google::Analytics::Data::V1beta::NumericValue: int64_value: 0>>>>
Array of and group expressions. Error occurs adding this array to top level filter and group
"google_analytics_objects.rb:173:in `method_missing': Expected repeated field array"
[
<Google::Analytics::Data::V1beta::FilterExpression:
filter: <Google::Analytics::Data::V1beta::Filter:
field_name: "sourceMedium",
string_filter: <Google::Analytics::Data::V1beta::Filter::StringFilter:
match_type: :EXACT,
value: "somestring",
case_sensitive: false>>>,
<Google::Analytics::Data::V1beta::FilterExpression:
filter: <Google::Analytics::Data::V1beta::Filter:
field_name: "transactions",
numeric_filter: <Google::Analytics::Data::V1beta::Filter::NumericFilter:
operation: :GREATER_THAN,
value: <Google::Analytics::Data::V1beta::NumericValue: int64_value: 0>>>>
]
API doc [https://cloud.google.com/ruby/docs/reference/google-analytics-data-v1beta/latest/Google-Analytics-Data-V1beta-FilterExpression][1]
解決策
このエラーは、gRPC のバーフィングのように見えます。配列を予期したときに別のものを受け取ったか、配列を受け取ったものの、配列内の何かが予期した種類の反復オブジェクトではないためです。
コードにプッシュするために渡される引数は配列ですか?その場合は、要素を個々の引数に分散するために、先頭にスプラット (*) を付ける必要があります。その式割り当ての protobuf が、繰り返される Expression 式 = 1 の行に沿った定義を持つメッセージを予期している場合。そして、要素の 1 つが要素の別の配列である配列オブジェクトを受け取ると、そのようなエラーが発生します。 expression=(value) 割り当てメソッドのドキュメントには、FilterExpression オブジェクトの配列が必要であることが示されており、コードでもそれが行われているように見えますが、コード内の変数名の一部は追跡されないため、いくつかの仮定を立てます。 …
Analytics_request_object_filter_expression_list の初期化が欠落していますが、Google::Analytics::Data::V1beta::FilterExpressionList として初期化されていると仮定します。
これが実際の問題行だと思います:
analytics_request_object_filter_expression_and_group.push(analytics_request_object_filter_expression_list)
タイプミスがあり、最後から 2 番目のアンダースコアがピリオドであると仮定すると、この行は、and_group アクセサー メソッドによって返された ExpressionList に ExpressionList 全体を (単一の要素として) 追加することになります (これにより、エラーが発生します)取得)。これはうまくいくと推測します。
analytics_request_object_filter_expression.and_group.push(
*analytics_request_object_filter_expression_list
)
ただし、API は and_group の割り当てメソッドとアクセサー メソッドを定義していますが、追加メソッドは定義していません…アクセサー メソッドによって返されたリストに対して #push を呼び出すと、技術的には新しい要素を追加するように機能しますが、Ruby の変数処理を使用してハッキングしています。オブジェクトがどのように対話できるように設計されているか。そのオブジェクトの and_group も、指定した内容に基づいてすでに空になっているはずなので、単にリストを and_group= 割り当てメソッドに渡すことをお勧めします。
# If you don't need to merge the list into the existing `and_group` list:
analytics_request_object_filter_expression.and_group = analytics_request_object_filter_expression_list
コンソールでコードを 1 行ずつ実行し、オブジェクトを詳しく調べることをお勧めします。