TASK_5.3_IMPLEMENTATION_SUMMARY.md 9.6 KB

Task 5.3 Implementation Summary: 向量搜索 DTO

任务概述

实现向量搜索应用层的数据传输对象(DTOs),用于在不同层之间传输数据。

任务要求:

  • 创建 application/vector_search/dtos.py,定义 DocumentDTO
  • 实现 DTO 与领域实体的转换方法
  • 满足需求 1.4 和 8.1

实现内容

1. 创建的文件

src/application/vector_search/dtos.py

定义了三个主要的 DTO 类:

  1. DocumentDTO - 文档数据传输对象

    • 属性:id, content, metadata, embedding, score, created_at, updated_at
    • 类方法:
      • from_entity() - 从领域实体创建 DTO
      • from_dict() - 从字典创建 DTO
    • 实例方法:
      • to_entity() - 转换为领域实体
      • to_dict() - 转换为字典
  2. SearchResultDTO - 搜索结果数据传输对象

    • 属性:document, score, rank
    • 类方法:
      • from_entity() - 从领域实体创建 DTO
      • from_dict() - 从字典创建 DTO
    • 实例方法:
      • to_dict() - 转换为字典
  3. SearchResponseDTO - 搜索响应数据传输对象

    • 属性:results, total, query_text, took_ms
    • 类方法:
      • from_dict() - 从字典创建 DTO
    • 实例方法:
      • to_dict() - 转换为字典

tests/unit/application/vector_search/test_dtos.py

完整的单元测试套件,包含 24 个测试用例:

TestDocumentDTO 类(13 个测试):

  • test_from_entity_basic - 测试从领域实体创建 DTO(基本情况)
  • test_from_entity_with_embedding - 测试包含嵌入向量的转换
  • test_from_entity_without_embedding - 测试不包含嵌入向量的转换
  • test_from_entity_with_score - 测试包含分数的转换
  • test_to_entity_basic - 测试将 DTO 转换为领域实体(基本情况)
  • test_to_entity_with_embedding - 测试包含嵌入向量的转换
  • test_to_dict_basic - 测试将 DTO 转换为字典(基本情况)
  • test_to_dict_with_optional_fields - 测试包含可选字段的转换
  • test_from_dict_basic - 测试从字典创建 DTO(基本情况)
  • test_from_dict_with_optional_fields - 测试包含可选字段的转换
  • test_roundtrip_entity_to_dto_to_entity - 测试实体 -> DTO -> 实体的往返转换
  • test_roundtrip_dict_to_dto_to_dict - 测试字典 -> DTO -> 字典的往返转换
  • test_metadata_is_copied - 测试元数据被复制而不是引用

TestSearchResultDTO 类(5 个测试):

  • test_from_entity_basic - 测试从领域实体创建搜索结果 DTO
  • test_from_entity_with_embedding - 测试包含嵌入向量的转换
  • test_to_dict - 测试将搜索结果 DTO 转换为字典
  • test_from_dict - 测试从字典创建搜索结果 DTO
  • test_roundtrip_dict_to_dto_to_dict - 测试往返转换

TestSearchResponseDTO 类(6 个测试):

  • test_to_dict_basic - 测试将搜索响应 DTO 转换为字典(基本情况)
  • test_to_dict_with_timing - 测试包含耗时的转换
  • test_from_dict_basic - 测试从字典创建搜索响应 DTO
  • test_from_dict_with_timing - 测试包含耗时的转换
  • test_roundtrip_dict_to_dto_to_dict - 测试往返转换
  • test_empty_results - 测试空结果列表

2. 更新的文件

src/application/vector_search/README.md

添加了 DTOs 的完整文档,包括:

  • 每个 DTO 类的属性说明
  • 类方法和实例方法的文档
  • 使用示例
  • 测试文件列表更新

设计决策

1. DTO 与领域实体的解耦

  • DTOs 使用基本类型(str, List[float], Dict)而不是值对象
  • 提供双向转换方法:from_entity()to_entity()
  • 元数据在转换时进行复制,避免修改原始数据

2. 可选字段处理

  • embedding 字段可选,通过 include_embedding 参数控制
  • score 字段可选,用于搜索结果场景
  • took_ms 字段可选,用于性能监控

3. 序列化支持

  • 提供 to_dict()from_dict() 方法支持 JSON 序列化
  • 可选字段在序列化时只在存在时包含

4. 时间戳处理

  • 使用 ISO 格式字符串表示时间戳
  • 通过 Timestamp.to_iso_string()Timestamp.from_iso_string() 进行转换

测试结果

所有 24 个测试用例全部通过:

========================= test session starts =========================
collected 24 items

tests/unit/application/vector_search/test_dtos.py::TestDocumentDTO::test_from_entity_basic PASSED [  4%]
tests/unit/application/vector_search/test_dtos.py::TestDocumentDTO::test_from_entity_with_embedding PASSED [  8%]
tests/unit/application/vector_search/test_dtos.py::TestDocumentDTO::test_from_entity_without_embedding PASSED [ 12%]
tests/unit/application/vector_search/test_dtos.py::TestDocumentDTO::test_from_entity_with_score PASSED [ 16%]
tests/unit/application/vector_search/test_dtos.py::TestDocumentDTO::test_to_entity_basic PASSED [ 20%]
tests/unit/application/vector_search/test_dtos.py::TestDocumentDTO::test_to_entity_with_embedding PASSED [ 25%]
tests/unit/application/vector_search/test_dtos.py::TestDocumentDTO::test_to_dict_basic PASSED [ 29%]
tests/unit/application/vector_search/test_dtos.py::TestDocumentDTO::test_to_dict_with_optional_fields PASSED [ 33%]
tests/unit/application/vector_search/test_dtos.py::TestDocumentDTO::test_from_dict_basic PASSED [ 37%]
tests/unit/application/vector_search/test_dtos.py::TestDocumentDTO::test_from_dict_with_optional_fields PASSED [ 41%]
tests/unit/application/vector_search/test_dtos.py::TestDocumentDTO::test_roundtrip_entity_to_dto_to_entity PASSED [ 45%]
tests/unit/application/vector_search/test_dtos.py::TestDocumentDTO::test_roundtrip_dict_to_dto_to_dict PASSED [ 50%]
tests/unit/application/vector_search/test_dtos.py::TestDocumentDTO::test_metadata_is_copied PASSED [ 54%]
tests/unit/application/vector_search/test_dtos.py::TestSearchResultDTO::test_from_entity_basic PASSED [ 58%]
tests/unit/application/vector_search/test_dtos.py::TestSearchResultDTO::test_from_entity_with_embedding PASSED [ 62%]
tests/unit/application/vector_search/test_dtos.py::TestSearchResultDTO::test_to_dict PASSED [ 66%]
tests/unit/application/vector_search/test_dtos.py::TestSearchResultDTO::test_from_dict PASSED [ 70%]
tests/unit/application/vector_search/test_dtos.py::TestSearchResultDTO::test_roundtrip_dict_to_dto_to_dict PASSED [ 75%]
tests/unit/application/vector_search/test_dtos.py::TestSearchResponseDTO::test_to_dict_basic PASSED [ 79%]
tests/unit/application/vector_search/test_dtos.py::TestSearchResponseDTO::test_to_dict_with_timing PASSED [ 83%]
tests/unit/application/vector_search/test_dtos.py::TestSearchResponseDTO::test_from_dict_basic PASSED [ 87%]
tests/unit/application/vector_search/test_dtos.py::TestSearchResponseDTO::test_from_dict_with_timing PASSED [ 91%]
tests/unit/application/vector_search/test_dtos.py::TestSearchResponseDTO::test_roundtrip_dict_to_dto_to_dict PASSED [ 95%]
tests/unit/application/vector_search/test_dtos.py::TestSearchResponseDTO::test_empty_results PASSED [100%]

========================= 24 passed in 0.40s ==========================

需求追溯

Requirement 1.4: 应用层协调领域对象完成用例

已满足 - DTOs 提供了应用层和表现层之间的数据传输机制,支持领域实体的转换。

Requirement 8.1: 向量数据库相关代码组织到独立模块

已满足 - DTOs 位于 src/application/vector_search/ 模块中,与向量搜索功能相关的其他组件组织在一起。

关键特性

  1. 类型安全:使用 dataclass 提供类型提示和验证
  2. 双向转换:支持 DTO ↔ 领域实体 ↔ 字典的双向转换
  3. 可选字段:灵活处理可选字段(embedding, score, took_ms)
  4. 数据隔离:元数据在转换时进行复制,避免意外修改
  5. 完整测试:24 个测试用例覆盖所有转换场景和边界情况
  6. 文档完善:详细的 docstring 和 README 文档

使用示例

从领域实体创建 DTO

from src.application.vector_search.dtos import DocumentDTO
from src.domain.vector_search.entities import Document

# 创建领域实体
doc = Document(...)

# 转换为 DTO(不包含嵌入向量)
dto = DocumentDTO.from_entity(doc)

# 转换为 DTO(包含嵌入向量)
dto = DocumentDTO.from_entity(doc, include_embedding=True)

# 转换为 DTO(包含搜索分数)
dto = DocumentDTO.from_entity(doc, score=0.95)

DTO 转换为领域实体

# 从 DTO 转换为领域实体
doc = dto.to_entity()

JSON 序列化

# 转换为字典(用于 JSON 序列化)
data = dto.to_dict()

# 从字典创建 DTO(用于 JSON 反序列化)
dto = DocumentDTO.from_dict(data)

搜索结果处理

from src.application.vector_search.dtos import SearchResultDTO, SearchResponseDTO

# 从领域实体创建搜索结果 DTO
result_dto = SearchResultDTO.from_entity(search_result)

# 创建搜索响应
response = SearchResponseDTO(
    results=[result_dto1, result_dto2],
    total=2,
    query_text="test query",
    took_ms=150
)

# 序列化为 JSON
json_data = response.to_dict()

下一步

Task 5.3 已完成。下一个任务是:

Task 5.4: 实现向量搜索命令处理器

  • 创建 application/vector_search/handlers.py
  • 实现 CreateDocumentHandler, UpdateDocumentHandler, DeleteDocumentHandler
  • 注入仓储和领域服务依赖

总结

Task 5.3 成功实现了向量搜索应用层的 DTOs,提供了:

  • 3 个 DTO 类(DocumentDTO, SearchResultDTO, SearchResponseDTO)
  • 完整的双向转换方法(DTO ↔ 领域实体 ↔ 字典)
  • 24 个单元测试,全部通过
  • 详细的文档和使用示例

实现遵循了分层架构原则,DTOs 作为应用层和表现层之间的桥梁,与领域实体解耦,提供了灵活的数据传输和序列化支持。