名称: mongodb-find-queries 版本: “2.1.0” 描述: 掌握使用过滤器、投影、排序和分页的MongoDB查找查询。学习查询运算符、比较、逻辑运算符和现实世界查询模式。用于从MongoDB集合中检索数据。 sasmp_version: “1.3.0” bonded_agent: 02-mongodb-queries-aggregation bond_type: PRIMARY_BOND
生产级技能配置
能力:
- 查询构建
- 过滤器运算符
- 投影设计
- 排序分页
- 文本搜索
输入验证: 必需上下文: - 集合名称 - 过滤条件 可选上下文: - 投影字段 - 排序顺序 - 分页参数
输出格式: 查询: 对象 选项: 对象 解释: 字符串 性能提示: 数组
错误处理: 常见错误: - 代码: FIND001 条件: “投影混合包含/排除” 恢复: “使用包含或排除,不要同时使用(除了_id)” - 代码: FIND002 条件: “排序内存限制超出” 恢复: “在排序字段上创建索引或使用allowDiskUse” - 代码: FIND003 条件: “无效的正则表达式模式” 恢复: “验证正则表达式语法,转义特殊字符”
先决条件: mongodb_version: “4.0+” 必需知识: - mongodb基础 - 查询运算符 索引要求: - “推荐在频繁过滤的字段上创建索引”
测试: 单元测试模板: | // 测试查找查询 const results = await collection.find(filter, { projection }).toArray() expect(results).toHaveLength(expectedCount) expect(results[0]).toHaveProperty(‘expectedField’)
MongoDB查找查询
掌握用于强大数据检索的find()方法。
快速开始
基本查询
// 查找一个文档
const user = await collection.findOne({ email: 'user@example.com' })
// 查找多个文档
const users = await collection.find({ status: 'active' }).toArray()
// 查找多个条件
const products = await collection.find({
price: { $gt: 100 },
category: 'electronics'
}).toArray()
查询运算符参考
比较运算符:
{ field: { $eq: value } } // 等于
{ field: { $ne: value } } // 不等于
{ field: { $gt: value } } // 大于
{ field: { $gte: value } } // 大于或等于
{ field: { $lt: value } } // 小于
{ field: { $lte: value } } // 小于或等于
{ field: { $in: [val1, val2] } } // 在数组中
{ field: { $nin: [val1, val2] } } // 不在数组中
逻辑运算符:
{ $and: [{field1: val1}, {field2: val2}] } // AND
{ $or: [{field1: val1}, {field2: val2}] } // OR
{ $not: {field: {$gt: 5}} } // NOT
{ $nor: [{field1: val1}, {field2: val2}] } // NOR
数组运算符:
{ field: { $all: [val1, val2] } } // 数组中所有值
{ field: { $elemMatch: {...} } } // 匹配数组元素
{ field: { $size: 5 } } // 数组大小恰好为5
投影(选择字段)
// 包含字段
db.users.findOne({...}, { projection: { name: 1, email: 1 } })
// 返回: { _id, name, email }
// 排除字段
db.users.findOne({...}, { projection: { password: 0 } })
// 返回: 除密码外的所有字段
// 隐藏_id
db.users.findOne({...}, { projection: { _id: 0, name: 1 } })
// 计算字段
db.users.findOne({...}, {
projection: {
firstName: 1,
lastName: 1,
fullName: { $concat: ['$firstName', ' ', '$lastName'] }
}
})
排序
// 升序排序 (1) 或降序排序 (-1)
db.products.find({}).sort({ price: 1 }).toArray() // 价格升序
db.products.find({}).sort({ createdAt: -1 }).toArray() // 最新优先
// 多字段排序
db.orders.find({}).sort({
status: 1, // 活动优先
createdAt: -1 // 然后最新
}).toArray()
// 不区分大小写排序
db.users.find({}).collation({ locale: 'en', strength: 2 }).sort({ name: 1 })
分页
// 方法1: 跳过和限制
const pageSize = 10
const pageNumber = 2
const skip = (pageNumber - 1) * pageSize
const results = await collection
.find({})
.skip(skip)
.limit(pageSize)
.toArray()
// 方法2: 基于游标(更适合大数据集)
const lastId = objectIdOfLastDocument
const results = await collection
.find({ _id: { $gt: lastId } })
.limit(pageSize)
.toArray()
文本搜索
// 首先创建文本索引
db.articles.createIndex({ title: 'text', content: 'text' })
// 搜索
db.articles.find(
{ $text: { $search: 'mongodb database' } },
{ score: { $meta: 'textScore' } }
).sort({ score: { $meta: 'textScore' } }).toArray()
// 短语搜索
db.articles.find({ $text: { $search: '"mongodb database"' } })
// 排除术语
db.articles.find({ $text: { $search: 'mongodb -relational' } })
正则表达式查询
// 区分大小写正则表达式
db.users.find({ email: { $regex: /^admin/, $options: '' } })
// 不区分大小写
db.users.find({ email: { $regex: /gmail/, $options: 'i' } })
// 多行
db.posts.find({ content: { $regex: /^mongodb/m } })
// 字符串模式
db.users.find({ email: { $regex: '^[a-z]+@gmail', $options: 'i' } })
高级查询模式
嵌套文档查询
// 查询嵌套字段
db.users.find({ 'address.city': 'New York' })
// 匹配整个嵌套文档
db.users.find({ address: { street: '123 Main', city: 'NY' } })
// 嵌套数组
db.orders.find({ 'items.productId': ObjectId(...) })
日期查询
// 日期范围
db.orders.find({
createdAt: {
$gte: new Date('2024-01-01'),
$lt: new Date('2024-12-31')
}
})
// 本周
const now = new Date()
const weekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000)
db.posts.find({ publishedAt: { $gte: weekAgo } })
空值处理
// 查找空值
db.users.find({ phone: null })
// 查找缺失字段
db.users.find({ phone: { $exists: false } })
// 查找非空
db.users.find({ phone: { $ne: null } })
// 不缺失
db.users.find({ phone: { $exists: true } })
性能提示
✅ 查询优化:
- 使用索引 在频繁过滤的字段上
- 早期过滤 - $match 在其他阶段之前
- 投影字段 - 不要获取不必要的数据
- 限制结果 - 使用分页
- 使用explain() - 分析每个查询
✅ 常见错误:
- ❌
find({})没有限制 - 返回所有文档 - ❌ 在过滤字段上没有索引 - 全集合扫描
- ❌ 获取不需要的字段 - 浪费带宽
- ❌ 排序没有索引 - 内存密集型
- ❌ 复杂正则表达式模式 - 性能慢
现实世界示例
用户搜索与分页
async function searchUsers(searchTerm, page = 1) {
const pageSize = 20
const skip = (page - 1) * pageSize
const users = await db.users
.find({
$or: [
{ name: { $regex: searchTerm, $options: 'i' } },
{ email: { $regex: searchTerm, $options: 'i' } }
]
})
.project({ password: 0 }) // 不返回密码
.sort({ name: 1 })
.skip(skip)
.limit(pageSize)
.toArray()
const total = await db.users.countDocuments({
$or: [
{ name: { $regex: searchTerm, $options: 'i' } },
{ email: { $regex: searchTerm, $options: 'i' } }
]
})
return {
data: users,
total,
pages: Math.ceil(total / pageSize),
currentPage: page
}
}
高级过滤
async function filterProducts(filters) {
const query = {}
if (filters.minPrice) query.price = { $gte: filters.minPrice }
if (filters.maxPrice) query.price = { ...query.price, $lte: filters.maxPrice }
if (filters.category) query.category = filters.category
if (filters.inStock) query.stock = { $gt: 0 }
if (filters.rating) query.rating = { $gte: filters.rating }
return await db.products
.find(query)
.sort({ [filters.sortBy]: filters.sortOrder })
.limit(filters.limit || 50)
.toArray()
}
下一步
- 创建示例查询 - 查找 + 过滤器
- 添加投影 - 选择所需字段
- 实现排序 - 排序结果
- 添加分页 - 处理大数据集
- 监控性能 - 使用explain()
你现在是MongoDB查询专家了! 🎯