- 模型层: EmbeddingResult/SearchResult 新增 sources 字段(主源居首,旧产物兜底) - M5 run_embedding: events/deduped 产物透传 sources 进 EmbeddingResult - M6 run_qdrant_ingest: payload 写入 sources(M5 → 回查 M4 → 兜底 [主源]) - vectorstore: 检索读取 payload.sources - 日报 HTML / CLI search / MCP: 多源显示「财联社 / 新浪 [多源]」 - 新增 scripts/backfill_qdrant_sources.py: 指纹库为权威源,scroll+upsert 回填存量 (本地模式 set_payload 逐点 0.65s 不可行,改走 ingest 同款快速路径) - 新增 tests/test_multisource.py 10 个;全量 276 passed
59 lines
1.8 KiB
Python
59 lines
1.8 KiB
Python
"""Qdrant 向量存储模块的数据模型 (M6)。"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from typing import Any
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class SearchFilter(BaseModel):
|
|
"""可选检索过滤条件,全部为 AND 关系。"""
|
|
|
|
source_id: str | None = None
|
|
source_ids: list[str] | None = None
|
|
stock_codes: list[str] | None = Field(default=None, description="match any")
|
|
company_names: list[str] | None = Field(default=None, description="match any")
|
|
industries: list[str] | None = Field(default=None, description="match any")
|
|
sentiment: str | None = None # positive / neutral / negative
|
|
importance_min: int | None = None # >= N
|
|
event_types: list[str] | None = None # match any
|
|
publish_date_from: str | None = None # YYYY-MM-DD
|
|
publish_date_to: str | None = None # YYYY-MM-DD
|
|
|
|
|
|
class SearchResult(BaseModel):
|
|
"""单条检索结果。"""
|
|
|
|
url_hash: str
|
|
score: float
|
|
title: str
|
|
url: str
|
|
source_id: str
|
|
sources: list[str] = Field(
|
|
default_factory=list,
|
|
description="全部来源(主源居首),来自 M3 去重多源记录;旧数据可能为空",
|
|
)
|
|
publish_time: datetime | None = None
|
|
event: dict[str, Any] | None = None # EventExtraction 展开的 dict
|
|
char_count: int | None = None
|
|
word_count: int | None = None
|
|
|
|
def short_summary(self) -> str:
|
|
codes = (
|
|
",".join((self.event or {}).get("stock_codes", []))
|
|
if self.event else "-"
|
|
)
|
|
return f"[{self.source_id}] score={self.score:.4f} 《{self.title[:40]}》 {codes}"
|
|
|
|
|
|
class CollectionInfo(BaseModel):
|
|
"""Collection 概览信息。"""
|
|
|
|
name: str
|
|
exists: bool
|
|
vectors_count: int
|
|
indexed_vectors_count: int | None = None
|
|
segments_count: int | None = None
|