1. 首页 > MongoDB教程 > 正文

MongoDB教程FG013-MongoDB查询语法与过滤实战

本文档风哥主要介绍MongoDB查询语法与过滤相关知识,包括MongoDB查询的概念、操作符、过滤条件、规划、最佳实践、性能优化、实现方法、优化以及生产案例等内容,风哥教程参考MongoDB官方文档CRUD Operations内容编写,适合DBA人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。

Part01-基础概念与理论知识

1.1 MongoDB查询的概念

MongoDB查询是指从集合中检索符合特定条件的文档的操作。MongoDB提供了丰富的查询操作符和方法,支持复杂的查询条件和过滤逻辑。查询操作是MongoDB中最常用的操作之一,对于数据检索和分析至关重要。更多视频教程www.fgedu.net.cn

MongoDB查询的特点:

  • 支持丰富的查询操作符
  • 支持嵌套文档和数组查询
  • 支持排序、分页和投影
  • 支持聚合查询
  • 支持索引优化
  • 支持地理空间查询

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”] } }

风哥提示:MongoDB查询操作符和过滤条件是构建高效查询的基础,掌握这些知识对于编写性能优异的查询语句至关重要。学习交流加群风哥微信: itpux-com

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. 应用程序优化
– 使用连接池
– 实现查询缓存
– 批量处理查询结果
– 避免频繁查询

生产环境建议:MongoDB查询规划应结合业务需求和数据模型,选择合适的查询策略和索引设计,确保查询性能满足业务要求。学习交流加群风哥QQ113257174

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/ } })

风哥提示:MongoDB查询优化是提高系统性能的关键,通过合理使用索引和优化查询语句,可以显著提升查询速度。更多学习教程公众号风哥教程itpux_com

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”) }
]

生产环境建议:MongoDB复杂查询应结合索引设计和查询优化技巧,确保查询性能满足业务需求。from MongoDB视频:www.itpux.com

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,利用其监控工具
  • 设置查询告警:为慢查询设置告警,及时发现问题
  • 定期性能分析:定期进行性能分析,优化查询语句
风哥提示:MongoDB查询监控是确保系统性能的重要手段,通过定期监控和分析,可以及时发现和解决查询性能问题。更多视频教程www.fgedu.net.cn

持续改进:MongoDB查询优化是一个持续的过程,需要根据业务需求和数据变化不断调整和改进,以确保系统的高效运行。

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息