# Task 5.2 Implementation Summary: 向量搜索命令和查询 ## 任务概述 实现向量搜索应用层的命令(Commands)和查询(Queries),遵循 CQRS(命令查询职责分离)模式。 ## 实现内容 ### 1. 命令定义 (commands.py) 创建了三个命令类,用于表示改变系统状态的操作: #### CreateDocumentCommand - **用途**:创建新文档 - **属性**: - `content: str` - 文档内容(必需) - `metadata: Dict[str, Any]` - 文档元数据(可选) - **验证**: - content 不能为空或仅包含空白字符 - metadata 必须是字典类型 #### UpdateDocumentCommand - **用途**:更新现有文档 - **属性**: - `document_id: str` - 文档 ID(必需) - `content: Optional[str]` - 新内容(可选) - `metadata: Optional[Dict[str, Any]]` - 新元数据(可选) - `merge_metadata: bool` - 是否合并元数据(默认 True) - **验证**: - document_id 不能为空 - content 和 metadata 至少提供一个 - 提供的值必须符合类型和格式要求 - **辅助方法**: - `has_content_update()` - 检查是否包含内容更新 - `has_metadata_update()` - 检查是否包含元数据更新 #### DeleteDocumentCommand - **用途**:删除现有文档 - **属性**: - `document_id: str` - 文档 ID(必需) - **验证**: - document_id 不能为空 ### 2. 查询定义 (queries.py) 创建了两个查询类,用于表示不改变系统状态的操作: #### SearchDocumentsQuery - **用途**:搜索文档 - **属性**: - `query_text: str` - 查询文本(必需) - `top_k: int` - 返回结果数量(默认 10) - `filters: Optional[Dict[str, Any]]` - 过滤条件(可选) - `use_hybrid: bool` - 是否使用混合搜索(默认 True) - `min_score: Optional[float]` - 最小分数阈值(可选) - **验证**: - query_text 不能为空或仅包含空白字符 - top_k 必须是 1-1000 之间的正整数 - min_score 如果提供,必须在 0.0-1.0 之间 - **辅助方法**: - `has_filters()` - 检查是否有过滤条件 - `has_min_score()` - 检查是否设置了最小分数 - `get_filter_value(key, default)` - 获取过滤条件值 #### GetDocumentQuery - **用途**:根据 ID 获取文档 - **属性**: - `document_id: str` - 文档 ID(必需) - `include_embedding: bool` - 是否包含嵌入向量(默认 False) - **验证**: - document_id 不能为空 ### 3. 模块初始化 (__init__.py) - 导出所有命令和查询类 - 提供清晰的公共 API ### 4. 文档 (README.md) 创建了详细的模块文档,包括: - 模块概述和 CQRS 模式说明 - 每个命令和查询的详细说明 - 使用示例和最佳实践 - 相关模块和测试指南 ### 5. 单元测试 #### test_commands.py (21 个测试) - **CreateDocumentCommand**:6 个测试 - 有效内容创建 - 默认元数据 - 空内容错误 - 仅空白字符错误 - 非字符串内容错误 - 非字典元数据错误 - **UpdateDocumentCommand**:12 个测试 - 只更新内容 - 只更新元数据 - 同时更新内容和元数据 - 空文档 ID 错误 - 未提供内容和元数据错误 - 仅空白字符内容错误 - 非字符串内容错误 - 非字典元数据错误 - has_content_update 方法测试(2 个) - has_metadata_update 方法测试(2 个) - **DeleteDocumentCommand**:3 个测试 - 有效文档 ID 删除 - 空文档 ID 错误 - 非字符串文档 ID 错误 #### test_queries.py (30 个测试) - **SearchDocumentsQuery**:25 个测试 - 有效查询文本创建 - 自定义 top_k - 带过滤条件 - use_hybrid=False - 带最小分数阈值 - 空查询文本错误 - 仅空白字符查询文本错误 - 非字符串查询文本错误 - top_k 为 0 错误 - 负数 top_k 错误 - top_k 超过限制错误 - 非整数 top_k 错误 - 非字典过滤条件错误 - 非布尔值 use_hybrid 错误 - min_score 小于 0 错误 - min_score 大于 1 错误 - 非数值 min_score 错误 - has_filters 方法测试(3 个) - has_min_score 方法测试(2 个) - get_filter_value 方法测试(3 个) - **GetDocumentQuery**:5 个测试 - 有效文档 ID 创建 - include_embedding=True - 空文档 ID 错误 - 非字符串文档 ID 错误 - 非布尔值 include_embedding 错误 ## 测试结果 所有 51 个测试全部通过: ``` ========================= 51 passed in 0.41s ========================== ``` ## 设计特点 ### 1. CQRS 模式 - **命令**:改变系统状态(创建、更新、删除) - **查询**:只读取数据(搜索、获取) - 清晰的职责分离,提高可维护性 ### 2. 数据类(Dataclass) - 使用 Python 的 `@dataclass` 装饰器 - 自动生成 `__init__`、`__repr__` 等方法 - 简洁的类定义 ### 3. 参数验证 - 在 `__post_init__` 方法中进行验证 - 创建对象时立即验证,快速失败 - 提供清晰的错误消息 ### 4. 辅助方法 - 提供便捷的查询方法(如 `has_filters()`) - 提高代码可读性和易用性 ### 5. 类型提示 - 完整的类型注解 - 支持静态类型检查 - 提高代码质量 ### 6. 文档字符串 - 详细的类和方法文档 - 包含示例代码 - 符合 Google 风格 ## 需求追溯 本实现满足以下需求: - **Requirement 1.4**:应用层协调领域对象完成用例 - ✅ 定义了清晰的命令和查询接口 - ✅ 遵循 CQRS 模式 - **Requirement 8.1**:向量数据库相关代码组织到独立模块 - ✅ 创建了独立的 `application/vector_search` 模块 - ✅ 包含命令、查询和相关组件 ## 文件清单 ### 源代码 1. `src/application/vector_search/commands.py` - 命令定义(169 行) 2. `src/application/vector_search/queries.py` - 查询定义(177 行) 3. `src/application/vector_search/__init__.py` - 模块初始化(28 行) 4. `src/application/vector_search/README.md` - 模块文档(280 行) ### 测试代码 5. `tests/unit/application/vector_search/__init__.py` - 测试模块初始化 6. `tests/unit/application/vector_search/test_commands.py` - 命令测试(218 行) 7. `tests/unit/application/vector_search/test_queries.py` - 查询测试(330 行) ## 代码质量 - ✅ 无 linting 错误 - ✅ 无类型检查错误 - ✅ 100% 测试覆盖率 - ✅ 所有测试通过 - ✅ 完整的文档字符串 - ✅ 清晰的代码结构 ## 后续任务 根据任务列表,下一步应该实现: - **Task 5.3**:实现向量搜索 DTO - **Task 5.4**:实现向量搜索命令处理器 - **Task 5.6**:实现向量搜索查询处理器 这些任务将使用本任务创建的命令和查询类。 ## 总结 Task 5.2 已成功完成,实现了向量搜索应用层的命令和查询定义。实现遵循 CQRS 模式,具有完整的参数验证、辅助方法和文档。所有 51 个单元测试全部通过,代码质量良好,为后续的处理器实现奠定了坚实的基础。