You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ruby客户端的GA4 Data API中添加筛选表达式列表?

使用google-analytics-data Ruby gem调用GA4 API时的FilterExpressionList赋值错误

我在Ruby客户端中使用google-analytics-data gem查询GA4 API,尝试将筛选表达式数组添加到FilterExpressionList时,在第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>>>>
]

问题修复方案

1. 重复字段赋值方式错误

Google Protobuf生成的Ruby类中,重复字段(repeated field)不能直接用=赋值数组,需要使用concat方法批量添加,或者在初始化对象时直接传入数组:

修复方式一:使用concat添加数组

替换报错行的代码:

# 原错误代码
analytics_request_object_filter_expression_list.expressions = analytics_request_object_filter_expression_list_expressions

# 修复后代码
analytics_request_object_filter_expression_list.expressions.concat(analytics_request_object_filter_expression_list_expressions)

修复方式二:初始化时直接传入数组

在创建FilterExpressionList对象时直接传入表达式数组:

# 替换原对象初始化代码
analytics_request_object_filter_expression_list = Google::Analytics::Data::V1beta::FilterExpressionList.new(
  expressions: analytics_request_object_filter_expression_list_expressions
)

2. 变量名拼写错误

代码末尾还有一个变量名拼写错误:

# 原错误代码
analytics_request_object_filter_expression.and_group = analytics_request_object_filter_expressions_list

# 修复后(变量名和之前定义的一致)
analytics_request_object_filter_expression.and_group = analytics_request_object_filter_expression_list

内容的提问来源于stack exchange,提问作者markhorrocks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 20:59:50