新手必看:MongoDB查询语法基础

在开始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)

示例:只返回 nameage 字段(排除 _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")

九、注意事项

  1. 条件顺序:MongoDB查询会自动优化顺序,无需手动调整。
  2. 性能问题:避免用 skip(n) 实现大数据分页,可改用基于 _id 的游标(如 _id > 上次ID)。
  3. 避免全表扫描:查询时尽量带上索引字段(如 agename),可大幅提升速度。

十、总结与练习

MongoDB查询语法核心是“条件+投影+排序+限制”,掌握以下步骤即可入门:
1. 确定查询条件(等于、比较、逻辑、正则等)。
2. 选择需要返回的字段(投影)。
3. 用 sort() 排序、limit() 限制结果。

建议:创建一个包含不同字段(字符串、数组、数字)的测试集合,尝试以下查询:
- 查询 age 等于25的用户,并只返回 name。
- 找出爱好包含 “coding” 且年龄小于25的用户。
- 按 age 降序,返回前3条结果。

通过实际操作,你会快速熟悉MongoDB的查询逻辑!

Xiaoye