MongoDB 常用语法与操作符整理
基本查询
find()
返回一个游标,可以用 next() 或 toArray() 处理结果。const cursor = db.collection.find({ name: "Tom" }) // 查询 name 为 Tom 的所有文档 const doc = cursor.next() // 获取下一个文档 const docs = cursor.toArray() // 获取所有文档为数组
findOne()
直接返回单个文档。const doc = db.collection.findOne({ age: 18 }) // 查询 age 为 18 的第一个文档
条件操作符
$eq
:等于db.collection.find({ age: { $eq: 18 } }) // 查询 age 等于 18 的文档
$ne
:不等于db.collection.find({ age: { $ne: 18 } }) // 查询 age 不等于 18 的文档
$gt
/$gte
:大于 / 大于等于db.collection.find({ age: { $gt: 18 } }) // 查询 age 大于 18 的文档 db.collection.find({ age: { $gte: 18 } }) // 查询 age 大于等于 18 的文档
$lt
/$lte
:小于 / 小于等于db.collection.find({ age: { $lt: 18 } }) // 查询 age 小于 18 的文档 db.collection.find({ age: { $lte: 18 } }) // 查询 age 小于等于 18 的文档
$in
/$nin
:匹配包含于数组中的值 / 不包含于数组中的值db.collection.find({ age: { $in: [18, 20, 22] } }) // 查询 age 为 18、20 或 22 的文档 db.collection.find({ age: { $nin: [18, 20, 22] } }) // 查询 age 不是 18、20 或 22 的文档
$all
匹配数组字段同时包含所有指定元素的文档。db.collection.find({ tags: { $all: ["red", "blue"] } }) // 查询 tags 同时包含 red 和 blue 的文档
$size
匹配数组字段长度。db.collection.find({ tags: { $size: 2 } }) // 查询 tags 数组长度为 2 的文档
$elemMatch
匹配数组中至少有一个元素满足指定条件。db.collection.find({ scores: { $elemMatch: { score: { $gt: 80 } } } }) // 查询 scores 数组中有 score 大于 80 的文档
逻辑操作符
$and
同时满足多个条件。db.collection.find({ $and: [{ age: 18 }, { name: "Tom" }] }) // 查询 age 为 18 且 name 为 Tom 的文档
$or
满足任意一个条件。db.collection.find({ $or: [{ age: 18 }, { name: "Tom" }] }) // 查询 age 为 18 或 name 为 Tom 的文档
$not
条件取反。db.collection.find({ age: { $not: { $gt: 18 } } }) // 查询 age 不大于 18 的文档
$nor
都不满足。db.collection.find({ $nor: [{ age: 18 }, { name: "Tom" }] }) // 查询 age 不是 18 且 name 不是 Tom 的文档
元素操作符
$exists
判断字段是否存在。db.collection.find({ email: { $exists: true } }) // 查询 email 字段存在的文档
$type
匹配字段类型。db.collection.find({ age: { $type: "int" } }) // 查询 age 字段类型为 int 的文档
正则查询
- 使用正则表达式进行模糊匹配。
db.collection.find({ name: /Tom/i }) // 查询 name 包含 Tom(不区分大小写)的文档
排序、限制、跳过
sort()
对结果排序。db.collection.find().sort({ age: -1 }) // 按 age 降序排序
limit()
限制返回数量。db.collection.find().limit(10) // 只返回前 10 条
skip()
跳过指定数量。db.collection.find().skip(5) // 跳过前 5 条
更新操作
updateOne()
更新匹配的第一条文档。db.collection.updateOne({ name: "Tom" }, { $set: { age: 20 } }) // 将 name 为 Tom 的文档 age 改为 20
updateMany()
更新所有匹配的文档。db.collection.updateMany({ age: { $lt: 18 } }, { $set: { status: "minor" } }) // 将 age 小于 18 的文档 status 改为 minor
$set
设置字段值。$unset
删除字段。$inc
字段递增。db.collection.updateOne({ name: "Tom" }, { $inc: { age: 1 } }) // 将 name 为 Tom 的文档 age 加 1
删除操作
deleteOne()
删除匹配的第一条文档。db.collection.deleteOne({ name: "Tom" }) // 删除 name 为 Tom 的文档
deleteMany()
删除所有匹配的文档。db.collection.deleteMany({ age: { $lt: 18 } }) // 删除 age 小于 18 的所有文档
聚合操作
aggregate()
聚合管道操作,用于对集合中的文档进行复杂的数据处理和分析。聚合由多个阶段组成,每个阶段使用管道符|
连接,常见阶段如下:$match
:过滤数据,相当于查询条件。{ $match: { age: { $gt: 18 } } } // 只处理 age 大于 18 的文档
$group
:分组统计,可以对分组后的数据进行聚合运算(如计数、求和等)。{ $group: { _id: "$status", count: { $sum: 1 } } } // 按 status 字段分组,并统计每组数量
$project
:指定输出字段,可以重命名、计算新字段等。{ $project: { name: 1, age: 1, isAdult: { $gte: ["$age", 18] } } } // 只输出 name、age,并新增 isAdult 字段
$sort
:排序。{ $sort: { age: -1 } } // 按 age 降序排序
$limit
:限制输出数量。{ $limit: 10 } // 只输出前 10 条
$skip
:跳过指定数量。{ $skip: 5 } // 跳过前 5 条
完整示例:
db.collection.aggregate([ { $match: { age: { $gte: 18 } } }, // 过滤 age 大于等于 18 的文档 { $group: { _id: "$status", avgAge: { $avg: "$age" }, count: { $sum: 1 } } }, // 按 status 分组,统计平均年龄和数量 { $sort: { avgAge: -1 } }, // 按平均年龄降序排序 { $limit: 5 } // 只显示前 5 个分组 ])
聚合操作示例
假设有如下集合数据:
[
{ name: "Tom", age: 20, status: "A" },
{ name: "Jerry", age: 25, status: "B" },
{ name: "Lucy", age: 22, status: "A" },
{ name: "Bob", age: 19, status: "B" }
]
统计每个 status 分组的平均年龄和人数,并按平均年龄降序排序,只显示前 2 个分组:
db.collection.aggregate([
{ $group: { _id: "$status", avgAge: { $avg: "$age" }, count: { $sum: 1 } } }, // 按 status 分组,统计平均年龄和数量
{ $sort: { avgAge: -1 } }, // 按平均年龄降序排序
{ $limit: 2 } // 只显示前 2 个分组
])
结果示例:
[
{ _id: "B", avgAge: 22, count: 2 },
{ _id: "A", avgAge: 21, count: 2 }
]
索引
索引用于加速 MongoDB 的查询操作,类似于关系型数据库中的索引。合理创建索引可以显著提升数据检索效率,尤其是在数据量较大时。
创建单字段索引
db.collection.createIndex({ name: 1 }) // 为 name 字段创建升序索引
1
表示升序,-1
表示降序。创建复合索引(多个字段)
db.collection.createIndex({ name: 1, age: -1 }) // 为 name 升序、age 降序创建复合索引
创建唯一索引(保证字段值唯一)
db.collection.createIndex({ email: 1 }, { unique: true }) // email 字段值不能重复
创建文本索引(支持模糊搜索)
db.collection.createIndex({ content: "text" }) // 对 content 字段创建全文索引
查看所有索引
db.collection.getIndexes() // 查看当前集合所有索引
删除索引
db.collection.dropIndex("索引名") // 删除指定索引
索引的作用:
- 提高查询效率,减少全表扫描
- 支持排序、唯一性约束、文本搜索等功能
- 但索引会增加写入和存储成本,建议只为高频查询字段创建索引
更多索引类型和高级用法可参考官方文档。