Skip to content

过滤器定义

学习如何在语义模型中定义可重用的过滤器

过滤器介绍

过滤器定义了可命名的、可重复使用的条件,这些条件解析为真或假。它们封装了常见的查询约束,使用户能够轻松应用预定义的条件而无需重复编写逻辑。可以将它们视为保存的片段或常见的WHERE子句。

使用过滤器可以使查询更简洁、更一致、更易于理解,将分析重点放在特定问题上而不是样板过滤逻辑上。

基本结构定义如下:

yaml
filters:
  - name: filter_name          # 必需: 唯一标识符(snake_case)
    description: "业务定义" # 必需: 清晰的解释
    expr: "SQL布尔表达式" # 可选(如果名称匹配布尔维度)
    args:                      # 可选: 用于参数化过滤器
      - name: param_name
        type: param_type
        description: "参数描述" # 必需
        default: default_value        # 可选

过滤器 vs 维度/度量

区分过滤器与维度和度量至关重要:

  • 维度:描述属性(如国家、状态)。用于分组、切片和直接过滤
  • 度量:可量化、可聚合的值。用于聚合函数和HAVING子句
  • 过滤器:定义可重复使用的条件或子集。必须解析为布尔值并生成WHERE子句逻辑

指导原则

  • 如果布尔概念描述直接属性(如用户存储的活动状态),使用布尔维度
  • 如果需要可重复使用的条件(特别是涉及计算、日期逻辑、组合属性或相关数据),使用过滤器

定义基础过滤器

基础过滤器定义简单的非参数化条件。

字段是否必需描述
name模型中过滤器的唯一名称
description解释过滤器代表的条件
expr定义过滤器逻辑的SQL表达式(必须评估为布尔值)
args参数化过滤器表达式的参数对象列表

示例:基础过滤器

yaml
filters:
  # 直接映射到布尔维度的过滤器(省略expr)
  - name: is_active
    description: 当前标记为活动的用户。

  # 基于单一维度表达式的过滤器
  - name: is_us_based
    description: 位于美国的用户。
    expr: "country = 'USA'"

  # 使用基于时间表达式的过滤器
  - name: recent_signups
    description: 最近90天内注册的用户。
    expr: "created_at >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)"

高级过滤器类型

过滤器可以包含参数或引用相关模型中的数据。

参数化过滤器

创建通过args接受用户输入的动态过滤器。使用双花括号引用参数。

示例:参数化过滤器

yaml
filters:
  - name: orders_within_date_range
    description: 选择在特定日期范围内(含)下单的订单。
    expr: "orders.order_date BETWEEN {{start_date}} AND {{end_date}}"
    args:
      - name: start_date
        type: date
        description: "过滤器范围的开始日期(YYYY-MM-DD)"
      - name: end_date
        type: date
        description: "过滤器范围的结束日期(YYYY-MM-DD)"

跨模型过滤器

过滤器可以基于相关模型中的数据定义条件,前提是存在关系。语义层使用这些关系在应用过滤器的查询中生成必要的连接或子查询。

示例:跨模型过滤器

yaml
filters:
  - name: customers_in_region_managed_by
    description: 选择位于分配给特定销售经理的区域的客户。
    expr: "region.sales_manager = {{manager_name}}"
    args:
      - name: manager_name
        type: string
        description: "要过滤的销售经理姓名"

最佳实践与注意事项

遵循这些指南以定义有效的过滤器。

通用最佳实践

  • 确保布尔输出:expr必须评估为布尔值(真/假)
  • 清晰命名与描述:使用描述性名称和清晰的描述
  • 匹配布尔维度:对于表示dimension = true的过滤器,名称应与布尔维度相同并省略expr
  • 记录依赖关系:明确说明对相关模型数据或参数的依赖

表达式最佳实践

  • 使用表前缀:强烈建议当expr涉及可能存在于其他模型中的字段时
  • 清晰性和可读性:编写清晰的expr逻辑
  • 空值处理:注意空值处理

良好表达式示例(参数化):

yaml
filters:
  - name: users_signed_up_between
    description: 基于注册日期范围过滤用户。
    expr: "users.created_at BETWEEN '{{start_date}}' AND '{{end_date}}'"
    args:
      - name: start_date
        type: date
        description: 开始日期(YYYY-MM-DD)
      - name: end_date
        type: date
        description: 结束日期(YYYY-MM-DD)

参数最佳实践

  • 显式类型:始终为每个参数定义类型
  • 参数字段:确保args列表中的每个参数包含必需字段
  • 默认值:为可选参数提供默认值
  • 清晰文档:为每个参数提供有意义的描述

综合示例

以下是客户模型上下文中的示例,包含各种过滤器类型和实践:

yaml
name: customers
description: >
  表示单个客户实体。包含联系信息、注册详情、
  位置和衍生指标如生命周期价值。
dimensions:
  - name: id
    description: 客户的唯一标识符。
    type: string
  - name: country
    description: 客户所在国家。
    type: string
  - name: is_active
    description: 布尔标志,指示客户账户当前是否被视为活动状态。
    type: boolean
filters:
  # 基础过滤器
  - name: is_active
    description: 当前标记为活动的客户。

  # 参数化过滤器
  - name: registered_after_date
    description: 在指定日期或之后注册的客户。
    expr: "customers.user_created_at >= '{{signup_date}}'"
    args:
      - name: signup_date
        type: date
        description: 最小注册日期(YYYY-MM-DD)

  # 跨模型过滤器
  - name: ordered_sku_recently
    description: "最近N天内订购特定SKU的客户。需要通过'orders'关系连接。"
    expr: "orders.product_sku = '{{sku}}' AND orders.order_date >= DATE_SUB(CURRENT_DATE(), INTERVAL {{days}} DAY)"
    args:
      - name: sku
        type: string
        description: 要检查的产品SKU
      - name: days
        type: number
        description: 回溯天数
        default: 30

下一步