# Momentry Search APIs 差異比較與使用指南

> **適用對象**: n8n 流程開發者、前端工程師  
> **更新日期**: 2026-04-17  
> **版本**: V1.0

---

## 1. 總覽: 四種搜尋模式

Momentry 提供四種搜尋 API，針對不同的情境進行優化。選擇正確的 API 可以大幅提升回應速度或準確度。

| API 端點 | 核心技術 | 主要優勢 | 推薦情境 |
|----------|----------|----------|----------|
| `/api/v1/search` | **語意向量 (Vector)** | 理解語境、同義詞匹配 | 標準搜尋、語意理解 |
| `/api/v1/n8n/search` | **語意向量 + 擴充資訊** | **提供 file_path 與 5W1H Metadata** | **n8n 自動化、需播放路徑** |
| `/api/v1/search/bm25` | **全文檢索 (Keyword)** | 精確匹配、零 Embedding 延遲 | 精確關鍵字、專有名詞 |
| `/api/v1/search/hybrid` | **向量 + BM25 混合** | 綜合語境與關鍵字準確度 | 要求最高準確度的場景 |

---

## 2. JSON 結構比較

### A. 標準搜尋 (Vector) vs n8n 搜尋

兩者後端邏輯幾乎一致（都使用 Qdrant 向量搜尋），但 **n8n/search** 提供了額外的欄位以滿足 n8n 流程中直接存取檔案的需求。

#### 標準搜尋 (`/api/v1/search`)
```json
{
  "query": "證明",
  "count": 1,
  "hits": [
    {
      "id": "sentence_0790",
      "vid": "384b0ff44aaaa1f14cb2cd63b3fea966",
      "chunk_type": "sentence",
      "start_frame": 187296,
      "end_frame": 187356,
      "fps": 59.94,
      "start_time": 3124.72,
      "end_time": 3125.73,
      "text": "I'm trying to prove it.",
      "score": 0.85,
      "vector_score": 0.85
    }
  ]
}
```
**特點**:
* 結構輕量，但包含完整定位資訊 (`start_frame`, `end_frame`, `fps`)。
* 適合前端列表展示與影片播放器定位。
* 現在與 `/n8n/search` 使用相同的欄位命名 (`id`, `vid`)。

#### n8n 搜尋 (`/api/v1/n8n/search`)
```json
{
  "query": "證明",
  "count": 1,
  "hits": [
    {
      "id": "sentence_0790",
      "vid": "384b0ff44aaaa1f14cb2cd63b3fea966",
      "chunk_type": "sentence",
      "start_frame": 187296,
      "end_frame": 187356,
      "fps": 59.94,
      "start_time": 3124.72,
      "end_time": 3125.73,
      "text": "I'm trying to prove it.",
      "score": 0.85,
      "vector_score": 0.85,
      "file_path": "/Users/accusys/momentry/var/sftpgo/data/...",
      "metadata": {
        "structured_summary": { ... }
      }
    }
  ]
}
```
**特點**:
* **欄位命名統一**: 現在與 `/search` 使用相同的 `id`, `vid` 命名。
* **擴充資訊**: 包含 `file_path`（可直接用於 ffprobe/ffmpeg 或播放器）。
* **Metadata**: 自動抓取該段落對應的 LLM 分析摘要（5W1H）。
* **精確定位**: 提供 `start_frame`, `end_frame` 與 `fps`，方便計算幀號。

### B. 關鍵字搜尋 (BM25)

#### BM25 搜尋 (`/api/v1/search/bm25`)
**特點**:
* **不使用 Qdrant**: 直接使用 PostgreSQL 的 `tsvector` (全文檢索)。
* **速度極快**: 省去了將 Query 轉換為向量的時間。
* **匹配方式**: 嚴格匹配詞彙（或經過分詞處理的詞彙），不具備語意聯想能力。

### C. 混合搜尋 (Hybrid)

#### 混合搜尋 (`/api/v1/search/hybrid`)
```json
{
  "query": "證明",
  "count": 1,
  "hits": [
    {
      "id": "sentence_0790",
      "vid": "384b0ff44aaaa1f14cb2cd63b3fea966",
      "chunk_type": "sentence",
      "start_frame": 187296,
      "end_frame": 187356,
      "fps": 59.94,
      "start_time": 3124.72,
      "end_time": 3125.73,
      "text": "I'm trying to prove it.",
      "score": 0.781,
      "vector_score": 0.85,
      "bm25_score": 0.62
    }
  ]
}
```
**特點**:
* **權重分配**: 預設 Vector 佔 70%，BM25 佔 30%。
* **雙重評分**: 同時回傳兩個原始分數與加權後的 `score` (combined)。
* **最準確**: 適合使用者輸入包含專有名詞（需 BM25）且帶有動作描述（需 Vector）的查詢。

---

## 3. 底層資源與效能分析

| 特性 | `/search` | `/n8n/search` | `/search/bm25` | `/search/hybrid` |
|------|-----------|---------------|----------------|------------------|
| **依賴資料庫** | Qdrant, Postgres | Qdrant, Postgres, MongoDB | Postgres | Postgres, MongoDB |
| **AI 模型呼叫** | Ollama (Embedding) | Ollama (Embedding) | **無** | Ollama (Embedding) |
| **Metadata 查詢** | 無 | **有 (Parent Chunk)** | **有 (Parent Chunk)** | 無 |
| **多維度搜尋** | ✅ (ASR+Face+Object+Scene) | ✅ (ASR+Face+Object+Scene) | ❌ (僅文字) | ❌ (僅 ASR) |
| **回應速度** | 快 (約 100-300ms) | 快 (約 100-300ms) | **極快 (<50ms)** | 中等 (計算較複雜) |
| **快取機制** | MongoDB | MongoDB | MongoDB | MongoDB |

> **提示**: 如果 n8n 流程只需要知道「出現在哪裡」，不需要播放影片或詳細摘要，使用 `/api/v1/search/bm25` 會比向量搜尋更省資源且更快。
> **新增**: 所有向量搜尋 API 現在支援多維度搜尋 (Multi-Modal)，同時查詢 ASR、Face、Object (YOLO)、Scene 四個 Collection，自動合併去重後回傳。

---

## 4. 使用建議決策樹

```text
你希望搜尋結果如何被使用？
│
├─ 用於 n8n 自動化流程，且需要播放影片片段或分析摘要？
│  └─ 使用 /api/v1/n8n/search (或 /n8n/search/bm25)
│
├─ 使用者輸入的是精確的專有名詞或特定句子？
│  └─ 使用 /api/v1/search/bm25
│
├─ 使用者輸入的是自然語言、意圖描述？ (例如："他在找什麼？")
│  ├─ 希望最快回應？ -> 使用 /api/v1/search
│  └─ 希望最準確？   -> 使用 /api/v1/search/hybrid
│
└─ 想要結合語意與關鍵字？
   └─ 使用 /api/v1/search/hybrid
```

---

## 5. 常見問題 (FAQ)

### Q: 為什麼 `/n8n/search` 的回應裡有 `metadata`？
A: 這是因為 `n8n/search` 會自動查詢該 Chunk 所屬的 **Parent Chunk**（通常是一段完整的場景或故事線）。Parent Chunk 包含了由 LLM (Gemma4) 分析出的結構化摘要（5W1H：Who, What, Where, When, Why）。這在 n8n 流程中可以省去再次呼叫 LLM 的成本。

### Q: 我應該如何處理 `file_path`？
A: `file_path` 是伺服器上的實體路徑。如果你在 n8n 的同一台機器上執行腳本，可以直接將此路徑傳給 Python 或 ffprobe 進行處理。

### Q: 為什麼有時候搜不到東西？
A: 
1. **Vector Search**: 如果 Query 太短或沒有明確語意，向量可能無法匹配到相似的 Context。
2. **BM25 Search**: 如果 Query 沒有經過分詞處理，或者包含停用詞，可能導致匹配失敗。

---

## 6. 版本歷史

| 版本 | 日期 | 內容 |
|------|------|------|
| V1.0 | 2026-04-17 | 建立比較文件，釐清各端點差異與底層資源 |
| V1.1 | 2026-04-17 | 統一 JSON 結構 (`id`, `vid`, `chunk_type`, `start_frame`/`end_frame`)，新增多維度搜尋說明 |
