MongoDB 查询文档

MongoDB 查询文档完整指南

(MongoDB 8.0+,2025 年最新实践)

核心结论
查询文档 = find() / findOne() + 查询条件 + 投影 + 选项
支持嵌套、数组、正则、地理、聚合、索引、实时流


一、核心查询命令

命令返回推荐场景
find(filter, projection)游标(Cursor)查询多条
findOne(filter, projection)单个文档null查询单条
countDocuments(filter)数量统计
distinct(field, filter)去重值数组枚举

二、基本查询示例

use company

// 1. 查询所有文档
db.employees.find().pretty()

// 2. 查询技术部员工
db.employees.find({ department: "技术部" }).pretty()

// 3. 查询单个员工(返回第一条)
db.employees.findOne({ name: "张三" })

三、查询操作符大全

类型操作符示例
比较$eq, $ne, $gt, $gte, $lt, $lte, $in, $nin{ age: { $gte: 30 } }
逻辑$and, $or, $not, $nor{ $or: [{ age: 25 }, { name: "李四" }] }
元素$exists, $type{ address: { $exists: true } }
数组$all, $elemMatch, $size{ skills: { $all: ["JS", "Python"] } }
正则$regex{ name: { $regex: /^张/ } }
投影1 / 0{ name: 1, age: 1, _id: 0 }

嵌套字段查询

// 查询地址在北京的员工
db.employees.find({ "address.city": "北京" })

// 更新嵌套字段(配合 $set)
db.employees.updateOne(
  { name: "张三" },
  { $set: { "address.zip": "100000" } }
)

数组查询

// 拥有 Python 技能的员工
db.employees.find({ skills: "Python" })

// 同时拥有 JS 和 Python
db.employees.find({ skills: { $all: ["JavaScript", "Python"] } })

// 技能数组长度为 3
db.employees.find({ skills: { $size: 3 } })

// 数组中某个对象满足条件
db.employees.find({
  scores: { $elemMatch: { subject: "math", score: { $gte: 90 } } }
})

四、游标操作(Cursor)

const cursor = db.employees.find({ department: "技术部" })

// 1. 遍历
cursor.forEach(doc => printjson(doc))

// 2. 转为数组
const docs = cursor.toArray()

// 3. 分页
cursor.skip(10).limit(5)

// 4. 排序
cursor.sort({ age: -1 })  // 降序
cursor.sort({ age: 1, name: -1 })  // 多字段

// 5. 投影(只返回 name 和 age)
cursor.projection({ name: 1, age: 1, _id: 0 })

五、常用查询方法

方法说明
.countDocuments(filter)精确计数
.estimatedDocumentCount()快速估计总数(无过滤)
.distinct("field")去重字段值
.findOneAndUpdate()查询 + 更新 + 返回
.aggregate()复杂统计
// 统计技术部人数
db.employees.countDocuments({ department: "技术部" })

// 获取所有部门(去重)
db.employees.distinct("department")

// 平均年龄
db.employees.aggregate([
  { $group: { _id: null, avgAge: { $avg: "$age" } } }
])

六、高级查询场景

1. 全文搜索(Text Index)

// 创建文本索引
db.articles.createIndex({ title: "text", content: "text" })

// 搜索包含 "MongoDB" 的文章
db.articles.find({ $text: { $search: "MongoDB" } })

2. 地理空间查询(2dsphere)

// 创建地理索引
db.stores.createIndex({ location: "2dsphere" })

// 查找附近 5km 的门店
db.stores.find({
  location: {
    $near: {
      $geometry: { type: "Point", coordinates: [116.4, 39.9] },
      $maxDistance: 5000
    }
  }
})

3. 正则表达式

// 姓名以 "李" 开头
db.employees.find({ name: { $regex: /^李/ } })

// 邮箱包含 gmail
db.employees.find({ email: { $regex: /@gmail\.com$/i } })

七、性能优化(索引是关键!)

// 创建索引
db.employees.createIndex({ department: 1 })           // 单字段
db.employees.createIndex({ age: 1, name: -1 })        // 复合索引
db.employees.createIndex({ skills: 1 })               // 数组索引
db.employees.createIndex({ "address.city": 1 })       // 嵌套字段

// 查看执行计划
db.employees.find({ department: "技术部" }).explain("executionStats")

索引原则

  • 查询频繁的字段建索引
  • 排序字段建索引
  • 复合索引遵循 等值 → 排序 → 范围 顺序

八、实时查询:Change Streams

// 监听 employees 集合的插入和更新
const changeStream = db.employees.watch([
  { $match: { operationType: { $in: ["insert", "update"] } } }
])

for await (const change of changeStream) {
  printjson(change.fullDocument)
}

九、GUI 工具查询

工具特点
MongoDB Compass可视化过滤器、聚合管道构建器
VS Code + MongoDB集成 IDE,实时查询
MongoDB AtlasWeb 界面,性能分析

十、常见错误与解决方案

错误原因解决方案
Query exceeded time limit查询太慢加索引、分页
Projection cannot have a mix of inclusion and exclusion投影混用 10_id 外不能混用
Text index required使用 $text 无文本索引createIndex({ field: "text" })
Cursor not found游标超时使用 noCursorTimeout()

十一、完整查询脚本示例

// query_employees.js
use company

print("员工查询报告\n")

// 1. 技术部 30岁以上员工(分页)
const techSenior = db.employees.find({
  department: "技术部",
  age: { $gte: 30 }
})
.sort({ age: -1 })
.skip(0)
.limit(10)
.projection({ name: 1, age: 1, skills: 1, _id: 0 })

print("技术部资深员工(前10名):")
techSenior.forEach(printjson)

// 2. 统计各部门人数
print("\n各部门人数统计:")
db.employees.aggregate([
  { $group: { _id: "$department", count: { $sum: 1 } } },
  { $sort: { count: -1 } }
]).forEach(printjson)

// 3. 查找技能包含 Python 的员工
const pythonDev = db.employees.find({ skills: "Python" }).countDocuments()
print(`\n掌握 Python 的员工:${pythonDev} 人`)

// 4. 最近入职的 3 人
print("\n最近入职员工:")
db.employees.find()
  .sort({ hireDate: -1 })
  .limit(3)
  .projection({ name: 1, hireDate: 1, _id: 0 })
  .forEach(printjson)

运行:

mongosh query_employees.js

十二、一句话总结

“MongoDB 查询 = find() + 条件 + 投影 + 索引 + 聚合”


快速查询模板

// 单条
db.users.findOne({ email: "a@example.com" })

// 多条件
db.posts.find({
  status: "published",
  tags: { $in: ["tech", "news"] },
  createdAt: { $gte: new Date("2025-01-01") }
})

// 分页
db.logs.find().sort({ ts: -1 }).skip(20).limit(10)

// 聚合统计
db.sales.aggregate([
  { $match: { status: "completed" } },
  { $group: { _id: "$product", total: { $sum: "$amount" } } }
])

官方文档

  • https://www.mongodb.com/docs/manual/reference/method/db.collection.find/
  • https://www.mongodb.com/docs/manual/tutorial/query-documents/

如需 复杂聚合管道全文搜索优化从 SQL SELECT 迁移实时查询订阅,欢迎继续提问!

文章已创建 2349

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部