# 指标公式检查功能 ## 功能概述 该功能用于解析和验证指标计算公式,自动提取公式中的变量并在Neo4j数据库中查找匹配的元数据记录。 ## 实现文件 ### 1. 核心业务逻辑 **文件**: `app/core/data_metric/metric_interface.py` **函数**: `metric_check(formula_text)` #### 功能描述 - 解析输入的计算公式文本 - 按运算符拆解公式,提取中文变量 - 在Neo4j数据库中查找匹配的元数据 - 返回变量及其匹配结果的JSON数组 #### 输入参数 - `formula_text` (str): 计算公式文本,格式为 "指标名称 = 计算表达式" #### 返回值 ```python [ { "variable": "变量名", "name_zh": "中文名称", "name_en": "英文名称", "id": 节点ID, "create_time": "创建时间", "findit": 1或0 } ] ``` #### 核心实现逻辑 1. **公式解析** - 按等号分割,提取等号右侧的计算表达式 - 使用正则表达式识别运算符:`+`, `-`, `*`, `/`, `()`, `()`, `[]`, `{}` - 按运算符分割表达式,提取所有token 2. **变量识别** - 过滤包含中文字符的token作为变量 - 自动过滤纯数字 - 对相同变量去重 3. **元数据匹配** - 使用Neo4j的CONTAINS进行模糊匹配 - 匹配DataMeta节点的name属性 - 每个变量返回第一个匹配结果 - 未找到时返回findit=0 ### 2. API接口 **文件**: `app/api/data_metric/routes.py` **路由**: `/api/data/metric/check` **方法**: `POST` #### 请求示例 ```json { "formula": "销售额 = 单价 * 数量 + 运费" } ``` #### 响应示例 ```json { "code": 200, "message": "success", "data": [ { "variable": "单价", "name_zh": "单价", "name_en": "unit_price", "id": 12345, "create_time": "2024-01-15 10:30:00", "findit": 1 }, { "variable": "数量", "name_zh": "数量", "name_en": "quantity", "id": 12346, "create_time": "2024-01-15 10:31:00", "findit": 1 }, { "variable": "运费", "name_zh": "", "name_en": "", "id": null, "create_time": "", "findit": 0 } ] } ``` ## 技术特点 ### 1. 灵活的公式解析 - 支持多种运算符:加、减、乘、除、括号 - 支持中英文括号 - 自动过滤数字 - 智能提取中文变量 ### 2. 智能匹配 - 使用Neo4j的CONTAINS实现模糊匹配 - 每个变量只查询一次,提高效率 - 明确标识是否找到匹配(findit字段) ### 3. 错误处理 - 完善的异常处理机制 - 详细的日志记录 - 友好的错误提示 ### 4. 性能优化 - 变量自动去重 - 使用Neo4j session批量查询 - 限制每个变量只返回一个结果(LIMIT 1) ## 使用场景 ### 1. 指标定义验证 在创建或编辑指标时,验证公式中的变量是否都存在于元数据库中。 ```python # 前端发送公式 formula = "利润率 = (销售收入 - 成本) / 销售收入 * 100" # 后端返回检查结果 # findit=1: 变量存在 # findit=0: 变量不存在,需要用户确认或创建 ``` ### 2. 数据血缘分析 了解指标依赖哪些基础元数据,便于进行数据血缘追踪。 ### 3. 数据质量检查 发现公式中引用但未在元数据库中定义的变量,提前预防数据质量问题。 ### 4. 智能提示 为用户提供变量的详细信息(中文名、英文名、创建时间等),辅助指标定义。 ## 示例场景 ### 场景1: 所有变量都存在 ``` 输入: "销售额 = 单价 * 数量" 结果: 单价和数量都在元数据库中找到(findit=1) 操作: 可以直接保存指标 ``` ### 场景2: 部分变量不存在 ``` 输入: "总成本 = 原材料成本 + 人工成本 + 其他费用" 结果: 原材料成本和人工成本找到,其他费用未找到(findit=0) 操作: 提示用户"其他费用"未定义,询问是否创建新元数据 ``` ### 场景3: 复杂计算公式 ``` 输入: "ROI = (投资收益 - 投资成本) / 投资成本 * 100" 结果: 返回投资收益和投资成本的匹配状态 操作: 根据匹配结果决定是否可以保存 ``` ## 扩展建议 ### 1. 增强匹配算法 - 实现更智能的模糊匹配(编辑距离、拼音匹配) - 支持同义词匹配 - 返回多个可能的匹配结果供用户选择 ### 2. 公式验证 - 验证公式的语法正确性 - 检查运算符使用是否合理 - 验证变量类型是否匹配运算要求 ### 3. 自动建议 - 基于历史数据推荐相似的变量 - 提供常用公式模板 - 智能补全变量名 ### 4. 可视化 - 显示变量之间的依赖关系图 - 标注未找到的变量 - 提供交互式的公式编辑器 ## 测试 测试文件位于: `tests/test_metric_check.py` 包含以下测试用例: 1. 简单公式测试 2. 复杂公式测试(多种运算符) 3. 无等号公式测试 4. 纯数字公式测试 5. 中文括号测试 6. 数据库连接失败测试 7. API接口测试 运行测试: ```bash python -m pytest tests/test_metric_check.py -v ``` ## 依赖 - Flask: Web框架 - Neo4j: 图数据库 - py2neo: Neo4j Python驱动 - re: 正则表达式库(Python标准库) ## 配置 无需额外配置,使用现有的Neo4j数据库连接。 ## 日志 使用应用级别的日志记录器,关键操作都有日志记录: - 公式解析开始 - 变量提取结果 - 数据库查询 - 匹配结果 - 错误信息 ## 维护建议 1. **定期检查日志**:了解用户常用的公式模式和未匹配的变量 2. **优化匹配规则**:根据实际使用情况调整匹配算法 3. **更新文档**:保持API文档与实现同步 4. **性能监控**:监控查询性能,必要时添加索引 ## 更新历史 - **2024-10-30**: 初始版本 - 实现基础公式解析功能 - 实现Neo4j元数据匹配 - 创建API接口 - 编写测试用例和文档