在开始MongoDB查询之前,我们先快速了解几个核心概念:集合(Collection) 类似于关系型数据库的“表”,文档(Document) 是MongoDB的基本数据单元,由键值对组成(类似JSON)。要进行查询,首先需要确保你已经连接到MongoDB并切换到目标数据库和集合。
一、连接与基础查询准备¶
假设你已安装MongoDB并启动服务,打开命令行工具(如终端或命令提示符),输入 mongo 进入MongoDB Shell。执行以下命令切换到测试数据库 test 并创建一个示例集合 users(类似“表”):
// 切换到test数据库
use test
// 插入测试数据(假设我们有一个用户集合,包含name、age、hobbies字段)
db.users.insertMany([
{ name: "Alice", age: 25, hobbies: ["reading", "gaming"] },
{ name: "Bob", age: 30, hobbies: ["sports"] },
{ name: "Charlie", age: 22, hobbies: ["reading", "coding"] },
{ name: "David", age: 18, hobbies: ["reading"] }
])
二、基本查询:find() 方法¶
find() 是MongoDB最核心的查询方法,用于从集合中检索文档。语法:
db.集合名.find(查询条件, 投影选项)
- 查询条件:指定要匹配的字段(不填则返回所有文档)
- 投影选项:指定返回哪些字段(0=不返回,1=返回,默认返回所有字段)
1. 查询所有文档¶
若想查看集合中所有用户,直接调用 find():
// 返回所有用户文档
db.users.find()
// 用pretty()美化输出(避免内容过长)
db.users.find().pretty()
三、条件查询:匹配特定文档¶
MongoDB通过“键值对”条件对象指定匹配规则,例如查询 name 为 “Alice” 的用户:
// 匹配 name 等于 "Alice" 的文档
db.users.find({ name: "Alice" })
常用比较操作符¶
MongoDB支持多种比较条件,以下是最常用的:
| 操作符 | 含义 | 示例 | 说明 |
|---|---|---|---|
$eq |
等于 | {age: 25} |
年龄等于25 |
$gt |
大于 | {age: {$gt: 20}} |
年龄 > 20 |
$lt |
小于 | {age: {$lt: 30}} |
年龄 < 30 |
$gte |
大于等于 | {age: {$gte: 18}} |
年龄 ≥ 18 |
$lte |
小于等于 | {age: {$lte: 30}} |
年龄 ≤ 30 |
$ne |
不等于 | {age: {$ne: 25}} |
年龄 ≠ 25 |
示例:查询年龄在20到30之间的用户($gt + $lt):
db.users.find({
age: { $gt: 20, $lt: 30 } // 同时满足两个条件(默认是 AND)
})
四、逻辑查询:组合条件¶
MongoDB支持 $and(默认)、$or、$not 等逻辑操作符,用于组合多个条件。
1. $and(默认)¶
多个条件同时满足时用 $and,但MongoDB会自动隐含 $and,无需显式写:
// 查询 age > 20 且 name 包含 "Bob" 的用户
db.users.find({
age: { $gt: 20 },
name: { $regex: "Bob" } // 正则匹配(见下文)
})
2. $or(满足任一条件)¶
若只需满足多个条件中的一个,用 $or:
// 查询 age > 30 或 name 是 "Alice" 的用户
db.users.find({
$or: [
{ age: { $gt: 30 } },
{ name: "Alice" }
]
})
3. $not(取反)¶
取反某个条件,例如查询“年龄不大于20”的用户:
db.users.find({
age: { $not: { $gt: 20 } } // 等价于 age ≤ 20
})
五、字符串与数组查询¶
1. 字符串匹配(模糊查询)¶
用正则表达式或 $regex 实现模糊匹配:
// 匹配 name 以 "A" 开头的用户
db.users.find({ name: /^A/ }) // 正则表达式写法
// 等价于
db.users.find({ name: { $regex: "^A" } })
2. 数组查询¶
若字段是数组(如 hobbies),可通过 $in(包含某元素)、$size(数组长度)等操作符查询:
| 操作符 | 含义 | 示例 | 说明 |
|---|---|---|---|
$in |
包含任一元素 | { hobbies: { $in: ["reading"] } } |
爱好包含 “reading” |
$size |
数组长度等于 | { hobbies: { $size: 2 } } |
爱好数组有2个元素 |
$elemMatch |
数组元素满足条件 | { hobbies: { $elemMatch: { $eq: "reading" } } } |
爱好数组中存在 “reading” |
示例:查询爱好包含 “reading” 且数组长度为2的用户:
db.users.find({
hobbies: {
$in: ["reading"], // 包含 "reading"
$size: 2 // 数组长度为2
}
})
六、投影查询:只返回指定字段¶
默认查询会返回文档所有字段,若只需特定字段,用投影参数(第二个参数):
- 1 表示返回该字段,0 表示不返回(_id 是默认返回的,需显式设为0)
示例:只返回 name 和 age 字段(排除 _id):
db.users.find(
{ age: { $gt: 20 } }, // 查询条件
{ name: 1, age: 1, _id: 0 } // 投影:只返回 name、age,不返回 _id
)
七、排序与限制结果¶
1. 排序(sort())¶
按字段排序,1 升序,-1 降序:
// 按 age 升序,name 降序
db.users.find().sort({ age: 1, name: -1 })
2. 限制结果(limit() 和 skip())¶
limit(n):最多返回n条结果skip(n):跳过前n条结果(常用于分页)
示例:返回前2条结果:
db.users.find().limit(2)
分页示例:跳过前2条,返回接下来2条:
db.users.find().skip(2).limit(2)
八、统计与去重¶
1. 统计文档数量(countDocuments())¶
// 统计年龄 > 20 的用户数量
db.users.countDocuments({ age: { $gt: 20 } })
2. 去重查询(distinct())¶
返回指定字段的所有不重复值:
// 查询所有不重复的爱好
db.users.distinct("hobbies")
九、注意事项¶
- 条件顺序:MongoDB查询会自动优化顺序,无需手动调整。
- 性能问题:避免用
skip(n)实现大数据分页,可改用基于_id的游标(如_id > 上次ID)。 - 避免全表扫描:查询时尽量带上索引字段(如
age、name),可大幅提升速度。
十、总结与练习¶
MongoDB查询语法核心是“条件+投影+排序+限制”,掌握以下步骤即可入门:
1. 确定查询条件(等于、比较、逻辑、正则等)。
2. 选择需要返回的字段(投影)。
3. 用 sort() 排序、limit() 限制结果。
建议:创建一个包含不同字段(字符串、数组、数字)的测试集合,尝试以下查询:
- 查询 age 等于25的用户,并只返回 name。
- 找出爱好包含 “coding” 且年龄小于25的用户。
- 按 age 降序,返回前3条结果。
通过实际操作,你会快速熟悉MongoDB的查询逻辑!