一次讲透)
Apache Ossie 表达式语言指南聚合函数与可分解性Distributive / Algebraic / Holistic一次讲透【免费下载链接】ossieApache Ossie, industry wide specification effort to standardize how we exchange semantic metadata across analytics, AI and BI platforms, providing a vendor neutral, single source of truth for semantic data项目地址: https://gitcode.com/GitHub_Trending/osi1/ossieApache Ossie 是 Apache 旗下的开源规范项目目标是标准化分析、AI 与 BI 平台之间交换语义元数据的方式为语义数据提供厂商中立的单一事实来源。本文聚焦 Ossie 表达式语言中的两块硬骨头聚合函数怎么写以及可分解性Decomposability为什么决定了指标能否被预聚合和分布式优化——这是写指标之前最该先建立的概念。Ossie 表达式语言在哪一层运行三层语义模型里的逻辑层速览先给结论表达式语言只服务于逻辑层Logical Layer也就是指标、字段、过滤器所在的那一层。Ossie 把语义模型分成三层可以把它当成一张地图来定位层职责表达式语言现状本体层Ontological Layer面向更抽象的业务概念建模接近 OWL 一类建模语言语言尚在另行定义中逻辑层Logical Layer对应传统 BI 语义模型metrics、fields、filters✅ 本文主角Ossie SQL 表达式语言物理层Physical Layer各数据库的原生 SQL由各引擎自行处理逻辑层的表达式语言有四个设计原则可移植核心函数在所有合规实现中行为一致、熟悉基于 ANSI SQL:2003 核心语法、分析聚焦优先覆盖 BI 高频函数、可扩展厂商可通过方言扩展核心能力。还有一个容易被忽略的边界这套语言用于声明模型declaring而不是查询接口。表达式里允许出现列/指标引用、CASE WHEN、算术与比较运算符、聚合函数、窗口函数等但SELECT/FROM/JOIN由语义层接管GROUP BY由粒度规格控制WHERE用模型的 filter 属性替代。换句话说你写的是这个指标是什么而不是帮我跑一条查询。完整定义见 core-spec/expression_language.md。一张能力地图看懂 Ossie 聚合函数从 SUM 到 APPROX_PERCENTILE这一节能拿到的是一张函数能力地图哪些是必选REQUIRED、哪些是推荐RECOMMENDED、各自什么语义、属于哪一类可分解性——一张表看完后面再按需查手册。类别函数语法含义可分解性要求级别核心聚合SUMSUM(expr)求和DistributiveREQUIRED核心聚合COUNTCOUNT(expr)非空值计数DistributiveREQUIRED核心聚合COUNT(*)COUNT(*)总行数DistributiveREQUIRED核心聚合COUNT(DISTINCT expr)COUNT(DISTINCT expr)去重计数HolisticREQUIRED核心聚合AVGAVG(expr)算术平均值AlgebraicREQUIRED核心聚合MIN/MAXMIN(expr)/MAX(expr)最小 / 最大值DistributiveREQUIRED统计聚合STDDEVSTDDEV(expr)样本标准差AlgebraicREQUIRED统计聚合STDDEV_POP/STDDEV_SAMPSTDDEV_POP(expr)等总体 / 样本标准差AlgebraicREQUIRED统计聚合VARIANCEVARIANCE(expr)样本方差AlgebraicREQUIRED统计聚合VAR_POP/VAR_SAMPVAR_POP(expr)等总体 / 样本方差AlgebraicREQUIRED分位数MEDIANMEDIAN(expr)中位数第 50 百分位HolisticREQUIRED分位数PERCENTILE_CONTPERCENTILE_CONT(p) WITHIN GROUP (ORDER BY expr)连续分位数插值HolisticREQUIRED分位数PERCENTILE_DISCPERCENTILE_DISC(p) WITHIN GROUP (ORDER BY expr)离散分位数实际值HolisticREQUIRED近似聚合APPROX_COUNT_DISTINCTAPPROX_COUNT_DISTINCT(expr)概率草图近似去重计数典型误差约 2%Sketch-basedRECOMMENDED近似聚合APPROX_PERCENTILEAPPROX_PERCENTILE(expr, p)近似分位数如 t-digest典型误差约 1%Sketch-basedRECOMMENDED其中p是 0 到 1 之间的数0.75即第 75 百分位。除了这张主表还有两个必选支持的增强用法值得单独留意-- DISTINCT 修饰SUM、COUNT 都支持 SUM(DISTINCT amount) COUNT(DISTINCT customer_id) -- 条件聚合所有聚合都应支持基于 CASE WHEN 的过滤式聚合 SUM(CASE WHEN status completed THEN amount ELSE 0 END) COUNT(CASE WHEN status completed THEN 1 END)条件聚合意味着先过滤再聚合不必依赖WHERE这在逻辑层里正好契合了表达式只声明、过滤交给 filter 属性的设计。可分解性怎么决定查询优化路径Distributive、Algebraic、Holistic 与 Sketch-based 四类详解这一节回答一个具体的工程问题一个指标能不能先分片算、再合并结果这直接决定了它能否走多阶段聚合、预聚合和分布式执行路径是语义引擎优化空间的来源。类别包含函数分片合并行为引擎视角的优化空间Distributive分布式SUM、COUNT、MIN、MAX各分片结果按同形运算直接合并和相加、极值取更大/更小最省——预聚合表可以完全替代明细扫描Algebraic代数式AVG、STDDEV、VARIANCE分片结果不能直接平均但保留少量中间量如总和 行数后即可公式换算合并中等——预聚合存中间量而非最终值合并时做一次代数运算Holistic整体式MEDIAN、PERCENTILE_CONT/DISC、COUNT(DISTINCT expr)分片结果无法合并必须回到全量数据小——常规路径只能全量计算Sketch-based草图式APPROX_COUNT_DISTINCT、APPROX_PERCENTILE用可高效合并的概率草图HyperLogLog、t-digest 等近似代替前两类大——牺牲约 1%~2% 精度换来分片可合并 用三个场景把差异讲透SUMDistributive把全国销量拆成华东、华北两片各自求和两片之和就是全国总和零误差、可无限分片。AVGAlgebraic两片各自的平均值不能直接再平均——两片行数不同直接平均会产生偏差。正确做法是每片保留总和 行数合并时做一次加权换算。MEDIANHolistic两片各自的中位数拼不出整体中位数左半区间可能全是小值、右半全是大值信息已经丢失必须回到明细数据。这就是为什么规范给每个函数都标注了可分解性它不是分类学兴趣而是写给执行引擎的优化说明书——Distributive 走预聚合 合并Algebraic 走中间量 公式Holistic 要么全量扫描、要么降级到 Sketch-based 近似。规范中提到的多阶段聚合扩展Analytical Context Extension正是建立在这套分类之上。在语义模型里写出聚合指标YAML 写法、多方言 dialects 与 NULLIF 防御性习惯结论先行聚合函数主要落在模型的metrics指标上指标定义在模型层级、可以跨多个数据集引用。下面以仓库自带的 TPC-DS 示例 examples/tpcds_semantic_model.yaml 为例从一个真实指标讲起。先算一个人效指标。示例中的store_productivity每员工销售额- name: store_productivity expression: dialects: - dialect: ANSI_SQL expression: SUM(store_sales.ss_ext_sales_price) / NULLIF(SUM(store.s_number_employees), 0) description: Sales per employee across stores datatype: Decimal ai_context: synonyms: - sales per employee - employee productivity这一行表达式里藏着两个值得学的写法防御性除法NULLIF(x, 0)在分母为 0 时返回 NULL 而不是报错。凡是写总量 ÷ 总量的比率指标都应该给它加上——分母来自另一个聚合时分母恰好为 0是迟早会发生的事。可分解性在组合指标上会变化分子分母都是SUMDistributive各自都能预聚合但两个可分解量相除整体不再可分解——你不能把各分片的人效平均起来得到总体人效。正确的执行路径是各分片分别合并分子、分母最后再除一次。再看多方言机制。指标的表达式挂在expression.dialects数组下同一个指标可以为不同引擎并列声明不同方言版本expression: dialects: - dialect: ANSI_SQL expression: DATE_TRUNC(month, order_date) - dialect: BIGQUERY expression: DATE_TRUNC(order_date, MONTH)比如DATE_TRUNC在 ANSI 与 BigQuery 里参数顺序相反BigQuery 的分位数则对应APPROX_QUANTILES(amount, 100)[OFFSET(50)]这类数组取元素写法。方言机制把这些引擎差异收进声明本身核心函数的语义保持一致——这正是 Ossie厂商中立单一事实来源的具体落点。另外注意ai_context.synonyms给指标配上同义词AI 检索和自然语言查询才能稳定命中它。完整函数清单与合规级别REQUIRED / RECOMMENDED / 方言扩展见 core-spec/expression_language.md指标结构的 schema 定义ai_context等字段见 core-spec/spec.md。从 Tableau / DAX 迁移过来聚合函数对照速查表这一节给一张精简速查表覆盖日常最高频的聚合函数完整对照日期、字符串、窗口函数在 core-spec/expression_language.md 的 Cross-Reference 章节。Ossie 标准TableauLooker StudioDAXSUM(x)SUM(x)SUM(X)SUM(x)COUNT(DISTINCT x)COUNTD(x)COUNT_DISTINCT(X)DISTINCTCOUNTNOBLANK(x)AVG(x)AVG(x)AVG(X)AVERAGE(x)STDDEV(x)STDEV(x)STDDEV(X)STDEV.S(x)VARIANCE(x)VAR(x)VARIANCE(X)VAR.S(x)PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY x)PERCENTILE(x, 0.75)PERCENTILE(X, 75)PERCENTILE.INC(x, 0.75)⚠️ 迁移时留意 DAX 与 SQL 的空值语义差异规范里专门给出了两条提醒DAX 的COUNT(x)对应 SQL 语义应选COUNTA都统计非空值但 DAXCOUNT不支持布尔列DAXDISTINCTCOUNT会把 BLANK 当作一个取值计入SQLCOUNT(DISTINCT x)则排除 NULL——可空列上会差 1建议改用DISTINCTCOUNTNOBLANK对齐。带走这三件事要点回顾与从 examples / validation 开始的上手路径最后收拢为三条可以记住的结论每个聚合函数都带一个可分解性标签它决定执行策略。Distributive 分片合并零代价Algebraic 需要中间量做公式换算Holistic 必须全量计算或改用 Sketch-based 近似约 1%~2% 误差。理解这个分类才能理解语义引擎的优化空间也才能判断这个指标能不能建预聚合表。核心函数必选、方言吸收差异。dialects数组让同一模型在 ANSI、Snowflake、BigQuery 等不同引擎上都正确运行写比率指标时记得NULLIF防除零。规范只声明、不查询。表达式语言描述模型是什么GROUP BY/WHERE等由语义层接管不要把查询 SQL 写进指标定义。上手路径建议克隆仓库开始动手git clone https://gitcode.com/GitHub_Trending/osi1/ossie通读 examples/tpcds_semantic_model.yaml它是覆盖聚合、窗口函数指标与多方言声明的完整样本对照 core-spec/expression_language.md 确认自己用到的函数是否属于 REQUIRED 集合用 validation/ 目录下的校验工具验证自己的语义模型若想扩展阅读语义结构见 core-spec/spec.md 与 docs/。【免费下载链接】ossieApache Ossie, industry wide specification effort to standardize how we exchange semantic metadata across analytics, AI and BI platforms, providing a vendor neutral, single source of truth for semantic data项目地址: https://gitcode.com/GitHub_Trending/osi1/ossie创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考