文章
高级搜索配置系统设计文档
目标:构建一个安全、灵活、可配置的 Doris 数仓表高级搜索系统,支持动态字段筛选、维度/指标分类、枚举值管理,并与现有元数据采集模块集成。
一、核心原则
- 仅支持 Doris 数仓表,禁止操作业务库(OLTP),避免影响生产查询性能;
- 高级搜索配置与原始元数据解耦,采用“配置快照”模式,元数据变更不影响已有配置;
- 字段配置可编辑、可扩展,支持维度/指标、数据类型、筛选开关、枚举值等;
- 用户交互简洁:初始导入 + 增量同步(新增/失效字段),已同步字段置灰不可操作;
- 枚举值手动维护,初期不依赖字典表,提升可控性与开发效率。
二、功能范围(MVP)
| 功能 | 说明 |
|---|---|
| ✅ 创建高级搜索配置 | 选择 Doris 数据源 + 表 → 弹窗导入字段 |
| ✅ 字段配置 | 每个字段可设:维度/指标、数据类型(string/number/date/enum)、是否可筛选、枚举值 |
| ✅ 枚举值输入 | 支持 值 或 码=值 格式(如 1=男,2=女) |
| ✅ 重新同步字段 | 仅展示新增字段(白)和已失效字段(红删除线),已同步字段灰显不可操作 |
| ✅ 查询使用 | 前端根据字段配置渲染筛选条件,后端动态拼 SQL 查询 Doris |
| ❌ 暂不支持 | 自动字典表拉取、业务库访问、配置版本历史、复杂聚合配置 |
三、数据模型设计
1. 主配置表:advanced_search_config
| 字段 | 类型 | 说明 |
|---|---|---|
id | BIGINT PK | 主键 |
name | VARCHAR(128) | 高级搜索名称(如“用户行为分析”) |
description | VARCHAR(255) | 描述(可选) |
category | VARCHAR(64) | 分类(如“用户域”) |
data_source_id | BIGINT NOT NULL | 关联元数据模块的 datasource.id |
table_name | VARCHAR(128) NOT NULL | Doris 表名 |
metadata_imported_at | DATETIME | 最后一次导入元数据时间 |
created_by | VARCHAR(64) | 创建人 |
created_at | DATETIME | 创建时间 |
updated_at | DATETIME | 更新时间 |
📌 唯一索引:(data_source_id, table_name)
📌 仅允许 Doris 类型数据源(前端/后端双重校验)
2. 字段配置表:advanced_search_field
| 字段 | 类型 | 说明 |
|---|---|---|
id | BIGINT PK | 主键 |
config_id | BIGINT NOT NULL | 外键,关联 advanced_search_config.id |
field_name | VARCHAR(128) NOT NULL | 原始字段名(如 user_id) |
display_name | VARCHAR(128) | 显示名称(如“用户ID”) |
field_role | ENUM('dimension','metric') | 维度 / 指标 |
data_type | ENUM('string','number','date','enum') | 数据类型 |
filterable | BOOLEAN DEFAULT true | 是否可用于筛选 |
enum_values | JSON | 仅 data_type=enum 时有效,格式见下文 |
is_deleted_in_source | BOOLEAN DEFAULT false | 元数据中是否已删除该字段 |
created_at | DATETIME | 创建时间 |
📌 唯一索引:(config_id, field_name)
📌 枚举值格式示例:
// 纯文本
["男", "女"]
// 码值映射
[{"code":"1","label":"男"}, {"code":"2","label":"女"}]四、枚举值处理规范
1. 前端输入
- 使用 Tag Input(标签输入框);
- 支持分隔符:逗号
,或回车; - 占位符提示:
例如:“1=男,2=女” 或 “是,否”; - 自动去重、去空格。
2. 后端解析逻辑
# 伪代码
def parse_enum(raw: str):
if not raw: return []
items = [s.strip() for s in raw.split(',') if s.strip()]
result = []
for item in items:
if '=' in item:
code, label = item.split('=', 1)
result.append({"code": code, "label": label})
else:
result.append({"code": item, "label": item})
return result3. 查询时使用
- 前端下拉选项显示
label,提交值用code(若存在); - 后端直接拼入 WHERE 条件(如
WHERE gender = '1'); - 明细/图表展示时,前端做 code → label 映射。
五、同步与变更管理
1. 初次导入
- 用户选择 Doris 表 → 弹窗展示所有字段(白色、可勾选);
- 保存后,字段写入
advanced_search_field,metadata_imported_at = NOW()。
2. 重新同步(增量)
- 对比当前元数据(来自元数据采集模块)与已配置字段;
- 弹窗仅展示两类字段:
- 新增字段:白色,可勾选导入;
- 已失效字段:红色删除线,不可操作,
is_deleted_in_source = true;
- 已同步字段:灰色 + 已勾选,不可取消(防误删)。
3. 元数据变更策略
- 不自动更新配置;
- 查询时若字段不存在,后端返回友好错误(前端 toast:“字段 xxx 已失效”);
- 配置保留,供用户决定是否删除。
五、同步与变更管理
1. 初次导入
- 用户选择 Doris 表 → 弹窗展示所有字段(白色、可勾选);
- 保存后,字段写入
advanced_search_field,metadata_imported_at = NOW()。
2. 重新同步(增量)
- 对比当前元数据(来自元数据采集模块)与已配置字段;
- 弹窗仅展示两类字段:
- 新增字段:白色,可勾选导入;
- 已失效字段:红色删除线,不可操作,
is_deleted_in_source = true;
- 已同步字段:灰色 + 已勾选,不可取消(防误删)。
3. 元数据变更策略
- 不自动更新配置;
- 查询时若字段不存在,后端返回友好错误(前端 toast:“字段 xxx 已失效”);
- 配置保留,供用户决定是否删除。
六、权限与安全
| 角色 | 权限 |
|---|---|
| 普通用户 | 仅可操作 data_source.type = 'doris' 的表 |
| 管理员 | 可操作所有数据源(但业务库操作需二次确认 + 审计日志) |
⚠️ MVP 阶段:前端数据源下拉框仅展示 Doris 类型,彻底规避风险。
七、API 与前后端协作建议
建议关键接口
POST /api/advanced-search/configs
# 创建配置 + 字段
GET /api/advanced-search/configs/{id}
# 获取配置 + 字段列表
POST /api/advanced-search/configs/{id}/sync-fields
# 重新同步字段(返回差异列表)
POST /api/advanced-search/query
# 执行高级搜索(接收 JSON 查询体)前端状态管理
- 字段列表用
config_id作为 key 缓存; - “重新同步”弹窗状态独立管理(不污染主配置);
- 枚举值输入使用受控组件(React State)。
八、后续可扩展点(非 MVP)
- 支持字段排序、是否在明细中显示;
- 配置版本历史 + 回滚;
- 自动从字典表拉取枚举值(需配置字典表映射);
- 高级聚合配置(如指标的 SUM/COUNT/DISTINCT);
- 权限按字段粒度控制。
九、附录:开发 checklist
- 后端建表
advanced_search_config+advanced_search_field - 前端:创建配置页面(数据源只能选 Doris)
- 前端:字段导入弹窗(Tag Input + 枚举格式提示)
- 后端:字段保存时解析
enum_values为标准 JSON - 前端:“重新同步”逻辑(仅展示新增/失效字段)
- 后端:查询接口使用 MyBatis Plus 动态拼 WHERE
- 前端:高级搜索表单根据字段配置渲染组件(日期/数字/枚举等)