
mongodb-natural-language-querying
热门使用自然语言生成只读的 MongoDB 查询(find)或聚合管道,并附带集合模式上下文和示例文档。当用户要求编写、创建或生成 MongoDB 查询,想要过滤/查询/聚合 MongoDB 中的数据,询问“如何查询...”,需要查询语法帮助,或讨论查找/过滤/分组 MongoDB 文档时,请使用此技能。也可用于将类似 SQL 的请求转换为 MongoDB 语法。不处理 Atlas Search($search 操作符)、向量/语义搜索($vectorSearch 操作符)、模糊匹配、自动补全索引或相关性评分——这些请使用 search-and-ai。不分析或优化现有查询——请使用 mongodb-query-optimizer。不处理涉及写入操作的聚合管道。需要 MongoDB MCP 服务器。
使用自然语言生成只读的 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-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 个字符,以防止过长的值消耗上下文。





