GA4 API PHP开发:过滤器异常及多文章阅读用户统计问题
一、需求背景
需统计旧数据中,读过指定50篇文章里至少2篇的用户数,无法提前设置内容分组或受众。
二、遇到的过滤器异常问题
1. NOT过滤器逻辑不符预期
两段代码分别统计访问过指定文章的用户($test)和用NOT过滤的用户($test2),理论上两者结果之和应等于总用户数,但实际不符,推测NOT过滤器筛选的是从未访问过该文章的用户,而非“访问过其他内容但未命中该文章”的用户。
代码片段:
$test->setDimensionFilter((new FilterExpression())->setFilter(new Filter ([ 'field_name' => 'pagePath', 'string_filter' => new Filter\StringFilter([ 'value' => $paths[0], 'match_type' => Filter\StringFilter\MatchType::CONTAINS, ]), ]))); $test2->setDimensionFilter((new FilterExpression())->setNotExpression(new FilterExpression([ 'filter' => new Filter([ 'field_name' => 'pagePath', 'string_filter' => new Filter\StringFilter([ 'value' => $paths[0], 'match_type' => Filter\StringFilter\MatchType::CONTAINS, ]), ]), ])));
2. AND过滤器返回无数据,OR过滤器正常
用AND过滤器筛选同时访问过两篇指定文章的用户($test3)时返回空,但GA4探索模式显示同会话有71用户、跨会话有91用户;改用setOrGroup则结果正常。
代码片段:
$test3->setDimensionFilter((new FilterExpression())->setAndGroup(new FilterExpressionList([ 'expressions'=> [ new FilterExpression([ 'filter' => new Filter([ 'field_name' => 'pagePath', 'string_filter' => new Filter\StringFilter([ 'value' => $paths[0], 'match_type' => Filter\StringFilter\MatchType::CONTAINS, ]), ]), ]), new FilterExpression([ 'filter' => new Filter([ 'field_name' => 'pagePath', 'string_filter' => new Filter\StringFilter([ 'value' => $paths[1], 'match_type' => Filter\StringFilter\MatchType::CONTAINS, ]), ]), ]), ] ]) ) );
三、问题原因分析
NOT过滤器的逻辑本质:GA4 API的维度过滤器基于事件级而非用户级筛选。NOT过滤器会排除所有包含目标pagePath的事件,只要用户有过一次符合条件的事件,就会被完全排除,而非仅排除该事件对应的记录。这导致
$test2统计的是从未触发过该pagePath事件的用户,而非“有其他访问行为但没碰过这篇文章”的用户,因此和$test的结果加起来不等于总用户数(总用户包含既访问过该文章也访问过其他页面的用户)。AND过滤器的局限性:维度过滤器的AND逻辑要求同一条事件记录同时满足多个条件,而用户访问两篇文章是两条独立的事件记录,自然匹配不到任何结果。这与GA4探索模式的逻辑不同——探索模式的用户级AND是判断用户是否有过多个符合条件的事件,而非单条事件满足所有条件。
四、统计“读过至少2篇指定文章”用户的解决方案
无需预定义受众或内容分组的可行方法:
方法1:BigQuery导出数据后处理
如果数据已导出到BigQuery,直接通过SQL统计,这是最准确高效的方式:
SELECT COUNT(DISTINCT user_pseudo_id) AS users_with_at_least_2_articles FROM `your-project-id.analytics_xxxxxx.events_*` WHERE _TABLE_SUFFIX BETWEEN '20240101' AND '20241231' -- 替换为目标时间范围 AND (page_path LIKE '%article-path-1%' OR page_path LIKE '%article-path-2%' OR ...) -- 列出所有50篇文章的路径 GROUP BY user_pseudo_id HAVING COUNT(DISTINCT page_path) >= 2;
方法2:API多请求后做集合运算
若必须使用GA4 API:
- 分别统计访问过每篇文章的用户集合(以
user_pseudo_id或userId为维度)。 - 在本地代码中计算这些集合的重叠情况,统计出至少出现在2个集合中的用户数量。
注意:这种方法需处理50次API请求,数据量较大时效率较低,适合小范围数据。
方法3:利用用户级指标筛选
若支持创建用户级计算指标(旧数据若无法在界面创建,可通过API配置),统计用户访问指定文章的次数,再通过metricFilter筛选次数≥2的用户。
内容的提问来源于stack exchange,提问作者Mattias Gonczi

