mongodb-natural-language-querying

mongodb-natural-language-querying

熱門

使用自然語言產生唯讀的 MongoDB 查詢(find)或聚合管線,並提供集合綱要上下文與樣本文件。當使用者要求撰寫、建立或產生 MongoDB 查詢、想要過濾/查詢/彙總 MongoDB 中的資料、詢問「如何查詢...」、需要查詢語法協助,或討論尋找/過濾/分組 MongoDB 文件時,請使用此技能。也可用於將類似 SQL 的請求轉換為 MongoDB 語法。不處理 Atlas Search($search 運算子)、向量/語意搜尋($vectorSearch 運算子)、模糊比對、自動完成索引或相關性評分——這些請使用 search-and-ai。不分析或最佳化現有查詢——請使用 mongodb-query-optimizer。不處理涉及寫入操作的聚合管線。需要 MongoDB MCP 伺服器。

164星標
30分支
更新於 2026/7/23
SKILL.md
唯讀
名稱
mongodb-natural-language-querying
描述

使用自然語言產生唯讀的 MongoDB 查詢(find)或聚合管線,並提供集合綱要上下文與樣本文件。當使用者要求撰寫、建立或產生 MongoDB 查詢、想要過濾/查詢/彙總 MongoDB 中的資料、詢問「如何查詢...」、需要查詢語法協助,或討論尋找/過濾/分組 MongoDB 文件時,請使用此技能。也可用於將類似 SQL 的請求轉換為 MongoDB 語法。不處理 Atlas Search($search 運算子)、向量/語意搜尋($vectorSearch 運算子)、模糊比對、自動完成索引或相關性評分——這些請使用 search-and-ai。不分析或最佳化現有查詢——請使用 mongodb-query-optimizer。不處理涉及寫入操作的聚合管線。需要 MongoDB MCP 伺服器。

MongoDB 自然語言查詢

您是 MongoDB 唯讀查詢與聚合管線的專家。

查詢產生流程

1. 使用 MCP 工具收集上下文

必要資訊:

  • 資料庫名稱與集合名稱(若未提供,請使用 mcp__mongodb__list-databasesmcp__mongodb__list-collections
  • 使用者對查詢的自然語言描述

依序取得:

  1. 索引(用於查詢最佳化):

    mcp__mongodb__collection-indexes({ database, collection })
    
  2. 綱要(用於欄位驗證):

    mcp__mongodb__collection-schema({ database, collection, sampleSize: 50 })
    
    • 回傳扁平化的綱要,包含欄位名稱與型別
    • 包含巢狀文件結構與陣列欄位
  3. 樣本文件(用於了解資料模式):

    mcp__mongodb__find({ database, collection, limit: 4 })
    
    • 顯示實際資料值與格式
    • 揭露常見模式(列舉、範圍等)

2. 分析上下文並驗證欄位

在產生查詢之前,務必根據您取得的綱要驗證欄位名稱。MongoDB 不會對不存在的欄位名稱報錯——它只會回傳空結果或出現非預期行為,導致錯誤難以診斷。透過先檢查綱要,您可以在使用者嘗試執行查詢之前就發現這些問題。

同時檢閱可用的索引,以了解哪些查詢模式效能最佳。

3. 選擇查詢類型:Find 與 Aggregation

優先使用 find 查詢而非聚合管線,因為 find 查詢較簡單,其他開發者也更容易理解。

使用 Find 查詢時機:

  • 對一個或多個欄位進行簡單過濾
  • 基本排序、限制或投影特定欄位
  • 不需要分組、複雜轉換或多階段處理

使用聚合管線時機(當請求需要):

  • 分組或聚合函數(sum、count、average 等)
  • 多個轉換階段
  • 與其他集合進行關聯($lookup)
  • 陣列展開或複雜陣列操作

4. 格式化您的回應

使用使用者要求的語言或驅動程式語法輸出查詢;如果未提供語言或預期格式,一律使用 MongoDB shell 語法(使用不帶引號的鍵與單引號),以確保可讀性並與 MongoDB 工具相容。

Find 查詢回應:

{
  "query": {
    "filter": "{ age: { $gte: 25 } }",
    "projection": "{ name: 1, age: 1, _id: 0 }",
    "sort": "{ age: -1 }",
    "limit": "10"
  }
}

聚合管線回應:

{
  "aggregation": {
    "pipeline": "[{ $match: { status: 'active' } }, { $group: { _id: '$category', total: { $sum: '$amount' } } }]"
  }
}

最佳實務

查詢品質

  1. 產生正確的查詢 - 建立符合使用者需求的查詢,然後檢查索引涵蓋範圍:
    • 產生能正確滿足所有使用者需求的查詢
    • 產生查詢後,檢查現有索引是否能支援該查詢
    • 如果沒有適當的索引,請在回應中提及(使用者可能想要建立一個)
    • 絕不使用 $where,因為它會阻止索引使用
    • 若無文字索引,請勿使用 $text
    • $expr 僅在必要時使用(謹慎使用)
  2. 避免冗餘運算子 - 切勿加入已被其他條件隱含的運算子:
    • 當您已經有相等或不等檢查時,不要加入 $exists(例如 status: "active"age: { $gt: 25 } 已隱含該欄位存在)
    • 不要加入重疊的範圍條件(例如不要同時使用 $gte: 0$gt: -1
    • 每個條件應增加尚未涵蓋的有意義過濾
  3. 僅投影需要的欄位 - 使用投影減少資料傳輸
    • 當不需要 _id 欄位時,在投影中加入 _id: 0
  4. 在使用欄位前根據綱要驗證欄位名稱
  5. 使用適當的運算子 - 為任務選擇正確的 MongoDB 運算子:
    • $eq$ne$gt$gte$lt$lte 用於比較
    • $in$nin 用於比對可能值的清單(相當於多個 $eq/$ne 條件以 OR 結合)
    • $and$or$not$nor 用於邏輯運算
    • $regex 用於區分大小寫的文字模式比對(盡可能使用左錨定模式如 /^prefix/,因為它們可以有效使用索引)
    • $exists 用於欄位存在性檢查(偏好使用 a: {$ne: null} 而非 a: {$exists: true},以利用可用索引)
    • $type 用於型別比對
  6. 最佳化陣列欄位檢查 - 使用高效模式進行陣列操作:
    • 檢查陣列是否非空:使用 "arrayField.0": {$exists: true} 而非 arrayField: {$exists: true, $type: "array", $ne: []}
    • 檢查第一個元素是否存在,比結合存在性、型別和不等檢查更簡單、易讀且高效
    • 對於多條件比對陣列元素,使用 $elemMatch
    • 對於陣列長度檢查,當需要精確計數時使用 $size

聚合管線品質

  1. 及早過濾 - 盡早使用 $match 以減少文件數量
  2. 最後投影 - 在最後使用 $project 以正確塑形回傳給客戶端的文件
  3. 盡可能限制 - 在 $sort 之後適當加入 $limit
  4. 使用索引 - 確保 $match$sort 階段能使用索引:
    • $match 階段放在管線開頭
    • 初始的 $match$sort 階段若位於任何修改文件的階段之前,則可使用索引
    • 產生 $match 過濾條件後,檢查索引是否能支援它們
    • 盡量減少在第一次 $match 之前轉換文件的階段
  5. 最佳化 $lookup - 對於頻繁關聯的資料,考慮反正規化

錯誤預防

  1. 根據綱要驗證所有欄位參考
  2. 正確引用欄位名稱 - 對巢狀欄位使用點記法
  3. 在正規表示式模式中跳脫特殊字元
  4. 檢查資料型別 - 確保欄位值與綱要中的欄位型別相符
  5. 地理空間座標 - MongoDB 的 GeoJSON 格式要求經度在前,緯度在後(例如 [longitude, latitude]{type: "Point", coordinates: [lng, lat]})。這與一般英文書寫座標的方式相反,因此在產生地理查詢時請務必再次確認。

綱要分析

當提供樣本文件時,分析:

  1. 欄位型別 - 字串、數字、布林、日期、ObjectId、陣列、物件
  2. 欄位模式 - 必填與選填欄位(檢查多個樣本)
  3. 巢狀結構 - 物件中的物件、物件陣列
  4. 陣列元素 - 同質與異質陣列
  5. 特殊型別 - 日期、ObjectId、二進位資料、GeoJSON

樣本文件使用

使用樣本文件來:

  • 了解實際資料值與範圍
  • 識別欄位命名慣例(camelCase、snake_case 等)
  • 偵測常見模式(例如狀態列舉、類別值)
  • 估計分組操作的基數
  • 驗證您的查詢能與真實資料搭配運作

錯誤處理

如果您無法產生查詢:

  1. 解釋原因 - 缺少綱要、請求不明確、查詢不可行
  2. 要求釐清 - 請求更多關於需求的細節
  3. 建議替代方案 - 如果可行,提出不同的方法
  4. 提供範例 - 顯示可能適用的類似查詢

範例工作流程

使用者輸入:「找出所有 25 歲以上的活躍使用者,按註冊日期排序」

您的流程:

  1. 檢查綱要中的欄位:statusageregistrationDate 或類似欄位
  2. 確認欄位型別符合查詢需求
  3. 根據使用者需求產生查詢
  4. 檢查可用索引是否能支援該查詢
  5. 如果查詢過濾條件沒有適當的索引,建議建立索引

產生的查詢:

{
  "query": {
    "filter": "{ status: 'active', age: { $gt: 25 } }",
    "sort": "{ registrationDate: -1 }"
  }
}

管理上下文大小

擷取大量或過多的樣本文件會浪費上下文,並可能降低查詢品質。

根據綱要寬度調整樣本數量:

  • < 30 個欄位:limit: 4(預設)
  • 30–80 個欄位:limit: 2
  • 80–150 個欄位:limit: 1
  • 150+ 個欄位:limit: 1,並僅投影與使用者查詢相關的欄位

預覽大型陣列欄位與字串:

  • 如果綱要文件包含陣列,請在樣本投影中使用 $slice: 3 來限制陣列大小。使用 $substr 將字串欄位限制為 100 個字元,以防止過長的值消耗上下文。