PostHog Actions 数据模型详解:system.actions 表结构与 HogQL 查询实战
【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthog
PostHog 中的 Actions(动作)是把多个事件与条件组合成命名规则的基础设施,它是洞察、群组、问卷乃至功能开关定向的共同抽象。本文基于 PostHog 官方 Skill 文档 models-actions.md.j2 展开,系统讲解system.actions系统表的结构、steps_json的 JSON 匹配规则,以及用matchesAction函数在事件流上检索 Action 命中事件的完整查询方式,并结合仓库源码印证matchesAction的底层解析逻辑与 Action 模型的字段定义。
Actions 是什么
文档对 Actions 的定义是:Actions are named combinations of events and conditions used for filtering and analysis——即"事件与条件的命名组合,用于过滤与分析"。在 PostHog 的 HogQL 体系中,每个 Action 对应系统表system.actions中的一行,可以通过execute-sql直接查询其元数据,也可以通过 HogQL 扩展函数matchesAction判断某条事件是否命中某个 Action。
理解 Actions 的关键在于它由两部分构成:
- 表级元数据:名称、描述、是否删除等,存放在
system.actions表中,是"这个 Action 是什么"; - 步骤级匹配规则:以 JSON 数组形式存放的
steps_json,是"这条事件算不算命中它"。
system.actions 表的列
该文档的列清单并非手写的静态表格,而是由 Jinja2 模板动态渲染:文档中的{{ schema_columns('system.actions') }}占位符会从live HogQL catalog(实时 HogQL 目录)生成列表。这一点在 SKILL.md 中被明确强调:
Every column table below is generated from the live HogQL catalog, so it lists exactly what
execute-sqlresolves.system.*tables expose a curated subset of each Django model, so a field returned by a REST tool such asinsight-getis not necessarily queryable — trust these tables over the REST response shape.
也就是说,system.*表暴露的是 Django 模型的精选子集——某个字段能通过 REST 工具返回,不代表它能被 HogQL 查询。以仓库源码为佐证,Action 模型定义 中可确认的字段包括:
name(CharField,max_length=400,可为空)description(TextField,默认空字符串)deleted(BooleanField,软删除标记)steps_json(JSONField,可为空)team(来自RootTeamMixin,多团队隔离)
这与文档中查询模式用到的列id, name, description, steps_json, deleted完全对应。从源码结构看,system.actions暴露的正是这些可查询列的映射。
steps_json 的结构与匹配选项
每个 Action 的匹配规则存放在steps_json字段中,是一个 JSON 数组,数组内每个元素是一个 step(步骤)。文档给出的示例结构如下:
[ { "id": "uuid", "event": "$pageview", "url": "https://example.com/pricing", "url_matching": "contains", "properties": [{ "key": "$current_url", "value": "pricing", "operator": "icontains" }] }, { "id": "uuid", "event": "button_clicked", "selector": "button.cta-primary", "text": "Sign Up", "text_matching": "exact" } ]其中第一个 step 通过事件名$pageview+ URL 包含匹配 +$current_url属性过滤三重条件命中"访问定价页";第二个 step 通过事件名button_clicked+ CSS 选择器 + 元素文本精确匹配命中"点击注册按钮"。
Step 匹配字段一览
文档为每个 step 字段定义了明确的语义:
| 字段 | 说明 | 取值/匹配方式 |
|---|---|---|
event | 要匹配的事件名 | 精确匹配 |
url | 要匹配的 URL 模式 | 与url_matching配合 |
url_matching | URL 匹配方式 | exact/contains/regex |
selector | 元素 CSS 选择器 | 精确匹配 |
text | 要匹配的元素文本 | 与text_matching配合 |
text_matching | 文本匹配方式 | exact/contains/regex |
properties | 附加属性过滤 | 标准属性过滤器列表 |
仓库源码 products/actions/backend/models/action.py 中ActionStepJSON的序列化逻辑印证了这些字段的存在——模型的to_dict方法会统计step.text、step.href、step.selector、step.url以及step.properties,说明这些是 step 的核心匹配维度。
关键语义:步骤之间是 OR 关系
文档在 Important Notes 中给出三条必须牢记的规则:
- Actions can combine multiple event conditions (steps):一个 Action 可以组合多个事件条件;
- Steps are OR'd together — matching any step triggers the action:步骤之间是OR关系,命中任意一个 step 即触发该 Action;
- Actions can be used in insights, cohorts, and feature flag targeting:Action 可用于洞察、群组和功能开关定向。
这一点直接决定了matchesAction的布尔语义:它是"事件是否命中 Action 的任意 step",而不是"是否依次经过所有 step"。
与其他模型的关系
文档在 Key Relationships 一节指出:Surveys——Actions 可以通过system.surveys表与问卷关联。问卷触发条件可以引用 Action,因此排查"问卷为什么没有触发"时,顺着system.surveys到其引用的 Action,再展开steps_json是标准排查路径。
常用查询模式
文档提供了三类可直接复用的查询模式。
1. 按名称查找 Action
用ILIKE模糊匹配名称,并用NOT deleted排除已软删除的记录:
SELECT id, name, description, steps_json FROM system.actions WHERE name ILIKE '%signup%' AND NOT deleted这个模式遵循了 SKILL.md 中"entity discovery"工作流:execute-sql用于发现实体(通常返回其 ID),再用专用读取工具按 ID 取完整实体——不要试图从 SQL 重建实体。
2. 查找包含特定事件的 Action
steps_json是 JSON 数组,事件名嵌套在每个 step 对象内。ClickHouse 的JSONExtractString可以按索引路径提取:
SELECT id, name, steps_json FROM system.actions WHERE NOT deleted AND JSONExtractString(steps_json, 1, 'event') = '$pageview'注意这里的1是数组第一个 step 的索引。从源码结构看可以推断:由于步骤是 OR 关系且数量可变,此查询只检查第一个 step——如果要精确找出"所有包含$pageview事件的 Action",应配合对整段 JSON 文本的包含匹配(如steps_json LIKE '%$pageview%')或拉回steps_json后在应用层解析。
3. 查找命中某个 Action 的事件
这是 Actions 最核心的查询能力——事件侧反向匹配,由 HogQL 扩展函数matchesAction提供。按 Action 名称:
SELECT count() FROM events WHERE matchesAction('clicked homepage button')按 Action ID:
SELECT count() FROM events WHERE matchesAction(43)matchesAction接受一个参数,既可以是 Action 名称字符串,也可以是 Action 的 ID 数字。它返回该 Action 定义所命中的事件集合,常用于统计"某个命名行为"的发生次数、作为洞察过滤条件,或与其他 HogQL 函数组合做漏斗/留存分析。
matchesAction 的源码实现印证
matchesAction并非 ClickHouse 原生函数,而是 PostHog HogQL 层定义的"宏函数"(macro),在查询解析期展开为标准 SQL 谓词。仓库源码可以确认其实现约束:
函数注册:在 posthog/hogql/functions/posthog.py 中,matchesAction以HogQLFunctionMeta("matchesAction", 1, 1)注册——即只接受恰好一个参数,与文档"按名称或按 ID 二选一"的用法严格对应,不存在"名称 + ID 同时传"的形态。
解析期展开:在 posthog/hogql/resolver.py 中,解析器识别到matchesAction后:
- 调用
_get_events_table_current_scope()获取当前作用域的 events 表别名; - 若当前查询上下文没有events 表(例如查的是
system.actions本身或其他表),直接抛出QueryError("matchesAction can only be used with the events table"); - 否则将其展开为基于该 Action 各 step 的匹配谓词(
matches_actionbuilder)。
这条QueryError给出了一个实操限制:matchesAction只能在以events表为查询目标的语句中使用。因此"查 Action 元数据"用FROM system.actions,"查命中事件"用FROM events,两条路径不可混用。
从 resolver 的结构看,matchesAction与getSurveyResponse、isLikelyBot等并列为 PostHog 的"posthog 宏函数"家族,这类函数在展开时会内联用户自定义的内容(Action 步骤),所以解析器还对其嵌套展开做了防护——文档中"Actions 可与system.surveys关联"的能力,正是与getSurveyResponse这条宏链共同支撑的。
使用建议与适用前提
结合 SKILL.md 的技能指引,使用 Actions 查询时应遵循:
- 发现走 SQL,读取走工具:先用
system.actions查询定位 Action(拿 ID),需要完整实体时再走 REST/读取工具,不要用 SQL 拼接实体; - 软删除过滤是默认习惯:所有对
system.actions的查询都应带NOT deleted,否则已删除的 Action 会污染结果; steps_json是数组:任何"包含某事件/某 URL"的筛选都要考虑多 step 的 OR 语义与数组索引问题;- 适用前提:上述查询均通过 PostHog 的 HogQL 执行入口(
execute-sql)运行,依赖当前团队的 HogQL catalog;system.*表是 Django 模型的 curated 子集,列的权威来源是运行时渲染的 catalog 文档而非 REST 响应形状。
小结
system.actions表 +steps_jsonJSON 结构 +matchesAction宏函数,构成了 PostHog Actions 从"元数据管理"到"事件匹配"的完整查询链路。元数据侧用标准 SQL 检索(名称模糊匹配、JSONExtractString提取 step 事件),事件侧用matchesAction按名称或 ID 直接圈定命中事件。理解"steps 之间是 OR 关系"和"matchesAction仅可用于 events 表"这两条语义,是正确写出 Actions 相关 HogQL 的前提。更多系统表 schema 可参考 querying-posthog-data 技能文档 下的其他 models 参考文件。
【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthog
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考