本文档风哥主要介绍MongoDB查询语法与过滤相关知识,包括MongoDB查询的概念、操作符、过滤条件、规划、最佳实践、性能优化、实现方法、优化以及生产案例等内容,风哥教程参考MongoDB官方文档CRUD Operations内容编写,适合DBA人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。
Part01-基础概念与理论知识
1.1 MongoDB查询的概念
MongoDB查询是指从集合中检索符合特定条件的文档的操作。MongoDB提供了丰富的查询操作符和方法,支持复杂的查询条件和过滤逻辑。查询操作是MongoDB中最常用的操作之一,对于数据检索和分析至关重要。更多视频教程www.fgedu.net.cn
- 支持丰富的查询操作符
- 支持嵌套文档和数组查询
- 支持排序、分页和投影
- 支持聚合查询
- 支持索引优化
- 支持地理空间查询
1.2 MongoDB查询操作符
MongoDB查询操作符是用于构建查询条件的特殊符号,主要包括:
# 1. 比较操作符
– $eq: 等于
– $ne: 不等于
– $gt: 大于
– $gte: 大于等于
– $lt: 小于
– $lte: 小于等于
– $in: 在指定数组中
– $nin: 不在指定数组中
# 2. 逻辑操作符
– $and: 逻辑与
– $or: 逻辑或
– $not: 逻辑非
– $nor: 逻辑 nor
# 3. 数组操作符
– $all: 包含所有指定元素
– $elemMatch: 数组元素匹配指定条件
– $size: 数组大小
# 4. 元素操作符
– $exists: 字段存在
– $type: 字段类型
# 5. 正则表达式操作符
– $regex: 正则表达式匹配
# 6. 地理空间操作符
– $geoWithin: 在指定区域内
– $near: 附近
– $geoIntersects: 相交
1.3 MongoDB过滤条件
MongoDB过滤条件是用于筛选文档的表达式,由字段名和操作符组成。过滤条件可以是简单的等式比较,也可以是复杂的逻辑组合。
# 简单过滤条件
{ field: value }
# 等于
{ field: { $gt: value } }
# 大于
# 复杂过滤条件
{
$and: [
{ field1: { $gt: value1 } },
{ field2: { $lt: value2 } }
]
}
# 嵌套文档过滤
{ “address.city”: “Beijing” }
# 数组过滤
{ “tags”: “mongodb” }
{ “tags”: { $all: [“mongodb”, “database”] } }
Part02-生产环境规划与建议
2.1 MongoDB查询规划
MongoDB查询规划要点:
# 1. 数据模型分析
– 了解文档结构和字段关系
– 分析数据访问模式
– 识别常用查询场景
# 2. 查询模式分析
– 识别高频查询
– 分析查询条件和排序需求
– 评估数据量和增长趋势
# 3. 索引策略规划
– 为常用查询创建合适的索引
– 考虑复合索引的顺序
– 避免过度索引
# 4. 性能目标设定
– 设定查询响应时间目标
– 评估并发查询能力
– 制定监控和优化策略
2.2 MongoDB查询最佳实践
MongoDB查询最佳实践:
- 使用索引:为常用查询创建合适的索引
- 限制返回字段:使用投影减少返回数据量
- 限制结果数量:使用limit限制返回结果
- 使用合适的查询操作符:选择最适合的操作符
- 避免全集合扫描:确保查询使用索引
- 合理使用排序:为排序字段创建索引
- 使用聚合管道:对于复杂查询使用聚合
- 监控查询性能:定期分析慢查询
2.3 MongoDB查询性能优化
MongoDB查询性能优化:
# 1. 索引优化
– 创建合适的单字段索引
– 使用复合索引优化多字段查询
– 考虑索引的选择性
– 定期重建索引
# 2. 查询优化
– 避免使用$where操作符
– 避免使用正则表达式开头的查询
– 合理使用$in操作符
– 避免查询大型数组
# 3. 服务器优化
– 增加服务器内存
– 优化存储系统
– 配置合适的WiredTiger缓存
– 调整查询超时设置
# 4. 应用程序优化
– 使用连接池
– 实现查询缓存
– 批量处理查询结果
– 避免频繁查询
Part03-生产环境项目实施方案
3.1 MongoDB查询方法
3.1.1 find方法
# 基本语法
db.collection.find(
# 示例:查询所有文档
fgedudb> db.fgedu_users.find()
# 示例:带过滤条件
fgedudb> db.fgedu_users.find({ age: { $gt: 25 } })
# 示例:带投影
fgedudb> db.fgedu_users.find({ age: { $gt: 25 } }, { name: 1, email: 1, _id: 0 })
# 示例:带排序
fgedudb> db.fgedu_users.find().sort({ age: -1 })
# 示例:带分页
fgedudb> db.fgedu_users.find().skip(10).limit(5)
3.1.2 findOne方法
# 基本语法
db.collection.findOne(
# 示例
fgedudb> db.fgedu_users.findOne({ name: “fgedu01” })
{
_id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”),
name: “fgedu01”,
email: “fgedu01@fgedu.net.cn”,
age: 25,
created_at: ISODate(“2026-04-08T08:00:00Z”)
}
3.1.3 aggregate方法
# 基本语法
db.collection.aggregate([
{ $match:
{ $group:
{ $sort:
…
])
# 示例
fgedudb> db.fgedu_orders.aggregate([
{ $match: { status: “completed” } },
{ $group: { _id: “$user_id”, total: { $sum: “$amount” } } },
{ $sort: { total: -1 } }
])
3.2 MongoDB查询实现
3.2.1 基本查询实现
# 1. 等值查询
fgedudb> db.fgedu_users.find({ name: “fgedu01” })
[
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”), name: “fgedu01”, email: “fgedu01@fgedu.net.cn”, age: 25 }
]
# 2. 范围查询
fgedudb> db.fgedu_users.find({ age: { $gte: 25, $lte: 30 } })
[
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”), name: “fgedu01”, email: “fgedu01@fgedu.net.cn”, age: 25 },
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h9”), name: “fgedu02”, email: “fgedu02@fgedu.net.cn”, age: 28 }
]
# 3. 逻辑查询
fgedudb> db.fgedu_users.find({ $and: [ { age: { $gt: 25 } }, { email: { $regex: “@fgedu.net.cn” } } ] })
[
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h9”), name: “fgedu02”, email: “fgedu02@fgedu.net.cn”, age: 28 }
]
# 4. 数组查询
fgedudb> db.fgedu_users.find({ tags: “mongodb” })
[
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”), name: “fgedu01”, tags: [“mongodb”, “database”] }
]
# 5. 嵌套文档查询
fgedudb> db.fgedu_users.find({ “address.city”: “Beijing” })
[
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”), name: “fgedu01”, address: { city: “Beijing”, street: “Main St” } }
]
3.2.2 高级查询实现
# 1. 正则表达式查询
fgedudb> db.fgedu_users.find({ name: { $regex: /^fgedu/ } })
[
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”), name: “fgedu01” },
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h9”), name: “fgedu02” }
]
# 2. 字段存在查询
fgedudb> db.fgedu_users.find({ email: { $exists: true } })
[
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”), name: “fgedu01”, email: “fgedu01@fgedu.net.cn” }
]
# 3. 字段类型查询
fgedudb> db.fgedu_users.find({ age: { $type: “number” } })
[
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”), name: “fgedu01”, age: 25 }
]
# 4. 数组元素匹配
fgedudb> db.fgedu_users.find({ tags: { $elemMatch: { $eq: “mongodb” } } })
[
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”), name: “fgedu01”, tags: [“mongodb”, “database”] }
]
# 5. 聚合查询
fgedudb> db.fgedu_orders.aggregate([
{ $match: { status: “completed” } },
{ $group: { _id: “$user_id”, total: { $sum: “$amount” } } },
{ $sort: { total: -1 } },
{ $limit: 5 }
])
[
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”), total: 1500 },
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h9”), total: 1200 },
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h0”), total: 900 }
]
3.3 MongoDB查询优化
3.3.1 索引优化
# 1. 创建单字段索引
fgedudb> db.fgedu_users.createIndex({ name: 1 })
name_1
# 2. 创建复合索引
fgedudb> db.fgedu_orders.createIndex({ user_id: 1, status: 1 })
user_id_1_status_1
# 3. 创建文本索引
fgedudb> db.fgedu_products.createIndex({ name: “text”, description: “text” })
name_text_description_text
# 4. 查看索引
fgedudb> db.fgedu_users.getIndexes()
[
{ v: 2, key: { _id: 1 }, name: ‘_id_’ },
{ v: 2, key: { name: 1 }, name: ‘name_1’ }
]
# 5. 分析查询执行计划
fgedudb> db.fgedu_users.find({ name: “fgedu01” }).explain()
{
queryPlanner: {
plannerVersion: 1,
namespace: ‘fgedudb.fgedu_users’,
indexFilterSet: false,
parsedQuery: { name: { ‘$eq’: ‘fgedu01’ } },
winningPlan: {
stage: ‘FETCH’,
inputStage: {
stage: ‘IXSCAN’,
keyPattern: { name: 1 },
indexName: ‘name_1’,
isMultiKey: false,
multiKeyPaths: { name: [] },
isUnique: false,
isSparse: false,
isPartial: false,
indexVersion: 2,
direction: ‘forward’,
indexBounds: { name: [“fgedu01”, “fgedu01”] }
}
},
…
},
…
}
3.3.2 查询优化技巧
# 1. 使用投影减少返回数据
fgedudb> db.fgedu_users.find({ age: { $gt: 25 } }, { name: 1, email: 1, _id: 0 })
# 2. 使用limit限制结果数量
fgedudb> db.fgedu_users.find().limit(10)
# 3. 使用skip和limit实现分页
fgedudb> db.fgedu_users.find().skip(10).limit(10)
# 4. 使用sort时创建索引
fgedudb> db.fgedu_users.createIndex({ age: -1 })
fgedudb> db.fgedu_users.find().sort({ age: -1 })
# 5. 避免使用$where操作符
# 不推荐
fgedudb> db.fgedu_users.find({ $where: “this.age > 25” })
# 推荐
fgedudb> db.fgedu_users.find({ age: { $gt: 25 } })
# 6. 避免使用正则表达式开头的查询
# 不推荐
fgedudb> db.fgedu_users.find({ name: { $regex: /edu/ } })
# 推荐
fgedudb> db.fgedu_users.find({ name: { $regex: /^fgedu/ } })
Part04-生产案例与实战讲解
4.1 MongoDB查询案例一:用户数据查询
4.1.1 需求分析
需要实现用户数据的多条件查询,包括按年龄范围、邮箱域名、注册时间等条件进行筛选。
4.1.2 解决方案
# 1. 创建索引
fgedudb> db.fgedu_users.createIndex({ age: 1 })
fgedudb> db.fgedu_users.createIndex({ email: 1 })
fgedudb> db.fgedu_users.createIndex({ created_at: -1 })
# 2. 按年龄范围查询
fgedudb> db.fgedu_users.find({ age: { $gte: 20, $lte: 30 } })
[
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”), name: “fgedu01”, age: 25 },
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h9”), name: “fgedu02”, age: 28 },
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h0”), name: “fgedu03”, age: 22 }
]
# 3. 按邮箱域名查询
fgedudb> db.fgedu_users.find({ email: { $regex: /@fgedu\.net\.cn$/ } })
[
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”), name: “fgedu01”, email: “fgedu01@fgedu.net.cn” },
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h9”), name: “fgedu02”, email: “fgedu02@fgedu.net.cn” }
]
# 4. 按注册时间查询
fgedudb> db.fgedu_users.find({ created_at: { $gte: new Date(“2026-04-01”), $lte: new Date(“2026-04-30”) } })
[
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”), name: “fgedu01”, created_at: ISODate(“2026-04-08T08:00:00Z”) }
]
# 5. 多条件组合查询
fgedudb> db.fgedu_users.find({
$and: [
{ age: { $gte: 25 } },
{ email: { $regex: /@fgedu\.net\.cn$/ } },
{ created_at: { $gte: new Date(“2026-04-01”) } }
]
})
[
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”), name: “fgedu01”, age: 25, email: “fgedu01@fgedu.net.cn”, created_at: ISODate(“2026-04-08T08:00:00Z”) },
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h9”), name: “fgedu02”, age: 28, email: “fgedu02@fgedu.net.cn”, created_at: ISODate(“2026-04-09T08:00:00Z”) }
]
4.2 MongoDB查询案例二:订单数据查询
4.2.1 需求分析
需要实现订单数据的查询,包括按用户ID、订单状态、订单金额等条件进行筛选,并计算订单总额。
4.2.2 解决方案
# 1. 创建索引
fgedudb> db.fgedu_orders.createIndex({ user_id: 1 })
fgedudb> db.fgedu_orders.createIndex({ status: 1 })
fgedudb> db.fgedu_orders.createIndex({ amount: 1 })
# 2. 按用户ID查询订单
fgedudb> db.fgedu_orders.find({ user_id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”) })
[
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h9”), user_id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”), amount: 100, status: “completed” },
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h0”), user_id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”), amount: 200, status: “pending” }
]
# 3. 按订单状态查询
fgedudb> db.fgedu_orders.find({ status: “completed” })
[
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h9”), user_id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”), amount: 100, status: “completed” },
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h1”), user_id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h9”), amount: 150, status: “completed” }
]
# 4. 按订单金额范围查询
fgedudb> db.fgedu_orders.find({ amount: { $gt: 100, $lt: 200 } })
[
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h1”), user_id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h9”), amount: 150, status: “completed” }
]
# 5. 计算用户订单总额
fgedudb> db.fgedu_orders.aggregate([
{ $match: { user_id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”) } },
{ $group: { _id: “$user_id”, total: { $sum: “$amount” } } }
])
[
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”), total: 300 }
]
# 6. 按状态分组计算总额
fgedudb> db.fgedu_orders.aggregate([
{ $group: { _id: “$status”, total: { $sum: “$amount” } } },
{ $sort: { total: -1 } }
])
[
{ _id: “completed”, total: 250 },
{ _id: “pending”, total: 200 }
]
4.3 MongoDB查询案例三:复杂条件查询
4.3.1 需求分析
需要实现复杂条件的查询,包括嵌套文档查询、数组查询、多条件逻辑组合等。
4.3.2 解决方案
# 1. 嵌套文档查询
fgedudb> db.fgedu_users.find({ “address.city”: “Beijing”, “address.zipcode”: “100000” })
[
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”), name: “fgedu01”, address: { city: “Beijing”, zipcode: “100000”, street: “Main St” } }
]
# 2. 数组查询
fgedudb> db.fgedu_users.find({ tags: { $all: [“mongodb”, “database”] } })
[
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”), name: “fgedu01”, tags: [“mongodb”, “database”, “nosql”] }
]
# 3. 数组元素匹配
fgedudb> db.fgedu_orders.find({ “items”: { $elemMatch: { product_id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h9”), quantity: { $gt: 1 } } } })
[
{
_id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h0”),
order_id: “order001”,
items: [
{ product_id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h9”), quantity: 2, price: 50 },
{ product_id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h1”), quantity: 1, price: 100 }
]
}
]
# 4. 复杂逻辑组合查询
fgedudb> db.fgedu_users.find({
$or: [
{ age: { $lt: 25 } },
{ $and: [
{ age: { $gte: 25, $lte: 30 } },
{ email: { $regex: /@fgedu\.net\.cn$/ } }
] }
]
})
[
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h0”), name: “fgedu03”, age: 22, email: “fgedu03@fgedu.net.cn” },
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”), name: “fgedu01”, age: 25, email: “fgedu01@fgedu.net.cn” },
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h9”), name: “fgedu02”, age: 28, email: “fgedu02@fgedu.net.cn” }
]
# 5. 分页查询
fgedudb> db.fgedu_users.find().sort({ created_at: -1 }).skip(0).limit(5)
[
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h9”), name: “fgedu02”, created_at: ISODate(“2026-04-09T08:00:00Z”) },
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h8”), name: “fgedu01”, created_at: ISODate(“2026-04-08T08:00:00Z”) },
{ _id: ObjectId(“6614f8a0a1b2c3d4e5f6g7h0”), name: “fgedu03”, created_at: ISODate(“2026-04-07T08:00:00Z”) }
]
Part05-风哥经验总结与分享
5.1 MongoDB查询技巧
MongoDB查询技巧:
- 使用合适的索引:为常用查询创建合适的索引,包括单字段索引和复合索引
- 限制返回字段:使用投影减少返回数据量,提高查询速度
- 限制结果数量:使用limit限制返回结果,避免返回过多数据
- 使用排序索引:为排序字段创建索引,提高排序性能
- 避免全集合扫描:确保查询使用索引,避免全集合扫描
- 合理使用聚合管道:对于复杂查询使用聚合管道,提高查询效率
- 监控查询性能:定期分析慢查询,优化查询语句
- 使用查询计划:使用explain()分析查询执行计划,优化查询
5.2 MongoDB查询脚本
#!/usr/bin/env mongosh
# query_scripts.js
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: `http://www.fgedu.net.cn`
// 连接到MongoDB实例
const conn = new Mongo(“192.168.1.100:27017”);
const db = conn.getDB(“fgedudb”);
// 复杂查询函数
function complexQuery() {
print(“执行复杂查询…”);
// 多条件查询
const result = db.fgedu_users.find({
$and: [
{ age: { $gte: 20, $lte: 35 } },
{ email: { $regex: /@fgedu\.net\.cn$/ } },
{ created_at: { $gte: new Date(“2026-01-01”) } }
]
}, {
name: 1,
email: 1,
age: 1,
_id: 0
}).sort({ created_at: -1 }).limit(10);
// 输出结果
print(“查询结果:”);
while (result.hasNext()) {
printjson(result.next());
}
}
// 聚合查询函数
function aggregateQuery() {
print(“\n执行聚合查询…”);
const result = db.fgedu_orders.aggregate([
{ $match: { status: “completed” } },
{ $group: { _id: “$user_id”, total: { $sum: “$amount” } } },
{ $sort: { total: -1 } },
{ $limit: 5 }
]);
print(“聚合结果:”);
while (result.hasNext()) {
printjson(result.next());
}
}
// 执行查询
complexQuery();
aggregateQuery();
print(“查询完成!”);
5.3 MongoDB查询监控
MongoDB查询监控建议:
- 启用慢查询日志:配置慢查询阈值,记录慢查询
- 使用数据库分析器:启用数据库分析器,收集查询统计信息
- 监控查询执行时间:定期检查查询执行时间,识别性能瓶颈
- 分析查询执行计划:使用explain()分析查询执行计划
- 监控索引使用情况:检查索引使用情况,优化索引设计
- 使用MongoDB Atlas:如果使用MongoDB Atlas,利用其监控工具
- 设置查询告警:为慢查询设置告警,及时发现问题
- 定期性能分析:定期进行性能分析,优化查询语句
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
