Skip to content

5.4 FilterState

学习目标

完成本节后,你将能够:

  1. 解释 Search Bar、facet sidebar、URL 和 query builder 为什么共享同一个 FilterState
  2. 读懂 singleFilter discriminated union 和 operator contract。
  3. 修改筛选语法前知道要同步 grammar、validate、lower、reverse adapter 和 SQL lowering。

5.4.1 先给结论

FilterState 是 UI 筛选和服务端查询之间的结构化契约。它不是某个组件的本地状态。

当前 v4 events 的状态关系是:

text
URL state = FilterState + searchQuery + searchType

Search Bar 和 facet sidebar 都只是这个状态的编辑器。最终查询只认结构化状态,不认 UI 文本,也不认某个侧边栏内部对象。

5.4.2 数据流

Search Bar 有 draft state,但 committed state 仍然来自 URL/filter state。这样两个编辑器不会各自维护最终筛选真相。

5.4.3 singleFilter 结构

源码:packages/shared/src/interfaces/filters.ts

singleFilter 是按 type 区分的 union:

typevalue 形状operator
datetimeDate><>=<=
stringstring=containsdoes not containstarts withends with
numbernumber=><>=<=
stringOptionsstring[]any ofnone of
categoryOptionsstring[] + keyany ofnone of
arrayOptionsstring[]any ofnone ofall of
stringObjectcolumn + key + stringstring operators
numberObjectcolumn + key + numbernumber operators
booleanboolean=<>
nullempty string valueis nullis not null
positionInTraceroot/first/last/nth=

eventsTableSingleFilter 又扩展了 events table 的 full-text matches operator,用在 string 和 stringObject filter 上。

5.4.4 Search Bar 不是第二套筛选系统

web/src/features/search-bar/README.md 给出的设计非常明确:

  • Search Bar 是 grammar editor,不替代 facet sidebar;
  • sidebar 的 FilterState 加上 full-text search 仍是单一事实源;
  • bar 的 local store 只保存 draft;
  • filterStateToQueryText 从 committed state 派生展示文本;
  • commit 时通过 planCommit -> validateQuery -> astToFilterState 写回 FilterState;
  • 不创建新的 URL param,也不维护第二份 committed copy。

这解决的是“两个筛选入口如何保持一致”的问题。

5.4.5 Search Bar 不变量

不变量含义
不静默丢弃 filtergrammar 不能表达的 filter 要保留或阻止 commit,不能偷偷删除。
validate 和 lower parity红色错误状态、commit gate、AST lowering 必须用同一上下文。
negation 不是 primitive- 要 lower 到已有 inverse operator,如 none ofdoes not containis null
URL 是 canonical sourcebar 和 sidebar 都从 URL/filter state 派生。
用户显式 filter 不被自动删除managed environment default 不能误删用户手写 filter。
skipped filters 要可解释grammar 暂不支持的 shape 不能假装支持。

这些不变量比 UI 交互细节更重要。修改 grammar 时先验证这些规则。

5.4.6 FilterState 如何进入查询

FilterState 本身不是 SQL。它要经过服务端 lowering:

query builder 还会额外做:

  • 自动 project filter;
  • trace_id equality 的 xxHash32 优化;
  • events_core / events_full 选择;
  • field set 选择;
  • 排序与 primary key 贴合。

所以新增筛选字段时,不是只改 UI,还要让服务端知道字段类型、operator、ClickHouse 表达式和性能影响。

5.4.7 修改筛选能力的同步面

改动同步位置
新增基础 filter 类型filters.ts、InMemoryFilterService、query lowering。
新增 events 字段search-bar field registry、FilterState column、query builder field map。
新增 operatorfilterOperators、validate、adapter、reverse adapter、SQL lowering。
新增 score/metadata key 语法quoted segment、completion、adapter、reverse adapter。
改 full-text 行为searchQuerysearchType、ClickHouse search lowering。
改 URL shapesidebar、search bar、saved views、recent searches、tests。

5.4.8 常见错误

错误后果
Search Bar 自己维护 committed filterssidebar 和 URL 不一致。
validate 支持但 lower 不支持Enter 无效或查询语义错。
lower 支持但 reverse adapter 不支持URL reload 后 filter 消失或文本不一致。
UI 新增 operator,SQL 没同步查询结果和界面承诺不一致。
手写 SQL filter绕过 tenant filter 和统一 operator 语义。

下一节

Query builder