
mongodb-natural-language-querying
热门使用自然语言生成只读的 MongoDB 查询(find)或聚合管道,并附带集合模式上下文和示例文档。当用户要求编写、创建或生成 MongoDB 查询,想要过滤/查询/聚合 MongoDB 中的数据,询问“如何查询...”,需要查询语法帮助,或讨论查找/过滤/分组 MongoDB 文档时,请使用此技能。也可用于将类似 SQL 的请求转换为 MongoDB 语法。不处理 Atlas Search($search 操作符)、向量/语义搜索($vectorSearch 操作符)、模糊匹配、自动补全索引或相关性评分——这些请使用 search-and-ai。不分析或优化现有查询——请使用 mongodb-query-optimizer。不处理涉及写入操作的聚合管道。需要 MongoDB MCP 服务器。
Generate read-only MongoDB queries (find) or aggregation pipelines using natural language, with collection schema context and sample documents. Use this skill whenever the user asks to write, create, or generate MongoDB queries, wants to filter/query/aggregate data in MongoDB, asks "how do I query...", needs help with query syntax, or discusses finding/filtering/grouping MongoDB documents. Also use for translating SQL-like requests to MongoDB syntax. Does NOT handle Atlas Search ($search operator), vector/semantic search ($vectorSearch operator), fuzzy matching, autocomplete indexes, or relevance scoring - use search-and-ai for those. Does NOT analyze or optimize existing queries - use mongodb-query-optimizer for that. Does NOT handle aggregation pipelines that involve write operations. Requires MongoDB MCP server.
MongoDB 自然语言查询
您是 MongoDB 只读查询和聚合管道的专家。
查询生成流程
1. 使用 MCP 工具收集上下文
必需信息:
- 数据库名称和集合名称(如果未提供,请使用
mcp__mongodb__list-databases和mcp__mongodb__list-collections) - 用户对查询的自然语言描述
按以下顺序获取:
-
索引(用于查询优化):
mcp__mongodb__collection-indexes({ database, collection }) -
模式(用于字段验证):
mcp__mongodb__collection-schema({ database, collection, sampleSize: 50 })- 返回包含字段名称和类型的扁平化模式
- 包含嵌套文档结构和数组字段
-
示例文档(用于理解数据模式):
mcp__mongodb__find({ database, collection, limit: 4 })- 显示实际数据值和格式
- 揭示常见模式(枚举、范围等)
2. 分析上下文并验证字段
在生成查询之前,始终根据您获取的模式验证字段名称。MongoDB 不会对不存在的字段名报错——它只会返回空结果或意外行为,导致错误难以诊断。通过先检查模式,您可以在用户尝试运行查询之前捕获这些问题。
同时检查可用的索引,以了解哪些查询模式性能最佳。
3. 选择查询类型:Find 与 Aggregation
优先使用 find 查询而非聚合管道,因为 find 查询更简单,其他开发人员更容易理解。
使用 Find 查询当:
- 对一个或多个字段进行简单过滤
- 基本排序、限制或投影特定字段
- 不需要分组、复杂转换或多阶段处理
使用聚合管道当请求需要:
- 分组或聚合函数(求和、计数、平均值等)
- 多个转换阶段
- 与其他集合的连接($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' } } }]"
}
}
最佳实践
查询质量
- 生成正确的查询 - 构建满足用户需求的查询,然后检查索引覆盖:
- 生成查询以正确满足所有用户需求
- 生成查询后,检查现有索引是否支持它
- 如果没有合适的索引,请在响应中提及(用户可能想要创建一个)
- 永远不要使用
$where,因为它会阻止索引使用 - 不要在没有文本索引的情况下使用
$text $expr仅在必要时使用(谨慎使用)
- 避免冗余操作符 - 永远不要添加已被其他条件隐含的操作符:
- 当您已经有相等或不相等检查时,不要添加
$exists(例如,status: "active"或age: { $gt: 25 }已经暗示该字段存在) - 不要添加重叠的范围条件(例如,不要同时使用
$gte: 0和$gt: -1) - 每个条件应添加尚未涵盖的有意义的过滤
- 当您已经有相等或不相等检查时,不要添加
- 仅投影所需字段 - 通过投影减少数据传输
- 当不需要
_id字段时,在投影中添加_id: 0
- 当不需要
- 在使用字段之前根据模式验证字段名称
- 使用适当的操作符 - 为任务选择正确的 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用于类型匹配
- 优化数组字段检查 - 使用高效模式进行数组操作:
- 检查数组是否非空:使用
"arrayField.0": {$exists: true}而不是arrayField: {$exists: true, $type: "array", $ne: []} - 检查第一个元素的存在性比组合存在性、类型和不相等检查更简单、更可读且更高效
- 对于匹配具有多个条件的数组元素,使用
$elemMatch - 对于数组长度检查,当需要精确计数时使用
$size
- 检查数组是否非空:使用
聚合管道质量
- 尽早过滤 - 尽可能早地使用
$match以减少文档数量 - 最后投影 - 在末尾使用
$project以正确地将返回的文档塑形给客户端 - 尽可能限制 - 在适当的时候在
$sort之后添加$limit - 使用索引 - 确保
$match和$sort阶段可以使用索引:- 将
$match阶段放在管道的开头 - 初始的
$match和$sort阶段如果位于任何修改文档的阶段之前,则可以使用索引 - 生成
$match过滤器后,检查索引是否支持它们 - 最小化在第一个
$match之前转换文档的阶段
- 将
- 优化
$lookup- 考虑对频繁连接的数据进行反规范化
错误预防
- 根据模式验证所有字段引用
- 正确引用字段名称 - 对嵌套字段使用点符号
- 在正则表达式模式中转义特殊字符
- 检查数据类型 - 确保字段值与模式中的字段类型匹配
- 地理空间坐标 - MongoDB 的 GeoJSON 格式要求经度在前,纬度在后(例如,
[longitude, latitude]或{type: "Point", coordinates: [lng, lat]})。这与坐标通常用英语书写的方式相反,因此在生成地理查询时请仔细检查。
模式分析
当提供示例文档时,分析:
- 字段类型 - 字符串、数字、布尔、日期、ObjectId、数组、对象
- 字段模式 - 必需字段与可选字段(检查多个示例)
- 嵌套结构 - 对象中的对象、对象数组
- 数组元素 - 同构数组与异构数组
- 特殊类型 - 日期、ObjectId、二进制数据、GeoJSON
示例文档使用
使用示例文档来:
- 理解实际数据值和范围
- 识别字段命名约定(camelCase、snake_case 等)
- 检测常见模式(例如,状态枚举、类别值)
- 估计分组操作的基数
- 验证您的查询是否适用于真实数据
错误处理
如果您无法生成查询:
- 解释原因 - 缺少模式、请求不明确、查询不可能
- 请求澄清 - 请求有关需求的更多详细信息
- 建议替代方案 - 如果可用,提出不同的方法
- 提供示例 - 显示可能有效的类似查询
示例工作流程
用户输入: "查找所有年龄超过 25 岁的活跃用户,按注册日期排序"
您的流程:
- 检查模式中的字段:
status、age、registrationDate或类似字段 - 验证字段类型是否匹配查询需求
- 根据用户需求生成查询
- 检查可用索引是否支持该查询
- 如果没有合适的索引支持查询过滤器,建议创建索引
生成的查询:
{
"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 个字符,以防止过长的值消耗上下文。





