Appearance
MongoDB CRUD操作
CRUD代表创建(Create)、读取(Read)、更新(Update)和删除(Delete),这是数据库操作的基本功能。在MongoDB中,这些操作通过各种方法实现,本章详细介绍MongoDB的CRUD操作。
创建操作(Create)
创建操作用于向集合中插入文档。
插入单个文档
insertOne()
insertOne()方法用于插入单个文档:
javascript
// 插入单个用户文档
db.users.insertOne({
name: "张三",
age: 25,
email: "zhangsan@example.com",
hobbies: ["读书", "游泳"],
address: {
city: "北京",
street: "中山路123号"
}
})
返回结果包含插入文档的_id和操作状态:
javascript
{
"acknowledged": true,
"insertedId": ObjectId("...")
}
插入多个文档
insertMany()
insertMany()方法用于插入多个文档:
javascript
// 插入多个用户
db.users.insertMany([
{
name: "李四",
age: 30,
email: "lisi@example.com"
},
{
name: "王五",
age: 28,
email: "wangwu@example.com"
},
{
name: "赵六",
age: 35,
email: "zhaoliu@example.com"
}
])
有序/无序插入
javascript
// 有序插入(默认)- 遇到错误停止
db.users.insertMany(docs, { ordered: true })
// 无序插入 - 遇到错误继续插入其余文档
db.users.insertMany(docs, { ordered: false })
读取操作(Read)
读取操作用于查询和检索文档。
基本查询
find()
find()方法用于查询文档:
javascript
// 查询所有文档
db.users.find()
// 查询所有年龄大于25的用户
db.users.find({ age: { $gt: 25 } })
// 查询特定字段
db.users.find({}, { name: 1, email: 1, _id: 0 })
findOne()
findOne()方法返回匹配的第一个文档:
javascript
// 查找名为"张三"的用户
db.users.findOne({ name: "张三" })
// 查找年龄最大的用户
db.users.findOne({}, { sort: { age: -1 } })
查询操作符
比较操作符
javascript
// $eq (等于)
db.users.find({ age: { $eq: 25 } })
// $gt (大于)
db.users.find({ age: { $gt: 25 } })
// $gte (大于等于)
db.users.find({ age: { $gte: 25 } })
// $lt (小于)
db.users.find({ age: { $lt: 30 } })
// $lte (小于等于)
db.users.find({ age: { $lte: 30 } })
// $ne (不等于)
db.users.find({ age: { $ne: 25 } })
// $in (在数组中)
db.users.find({ age: { $in: [25, 30, 35] } })
// $nin (不在数组中)
db.users.find({ age: { $nin: [20, 21, 22] } })
逻辑操作符
javascript
// $and
db.users.find({
$and: [
{ age: { $gte: 25 } },
{ age: { $lte: 35 } }
]
})
// $or
db.users.find({
$or: [
{ age: { $lt: 25 } },
{ age: { $gt: 35 } }
]
})
// $not
db.users.find({
age: { $not: { $in: [20, 21, 22] } }
})
// $nor
db.users.find({
$nor: [
{ age: { $lt: 20 } },
{ age: { $gt: 40 } }
]
})
元素操作符
javascript
// $exists (字段存在)
db.users.find({ email: { $exists: true } })
// $type (字段类型)
db.users.find({ age: { $type: "number" } })
评估操作符
javascript
// $regex (正则表达式)
db.users.find({ name: { $regex: "^张" } })
// $text (文本搜索)
db.users.find({ $text: { $search: "张三" } })
// $where (JavaScript表达式)
db.users.find({
$where: "this.age > this.name.length"
})
数组操作符
javascript
// $all (包含所有元素)
db.users.find({ hobbies: { $all: ["读书", "游泳"] } })
// $elemMatch (数组元素匹配)
db.users.find({
scores: {
$elemMatch: { subject: "数学", score: { $gte: 90 } }
}
})
// $size (数组大小)
db.users.find({ hobbies: { $size: 2 } })
查询投影
投影用于指定返回的字段:
javascript
// 只返回name和email字段
db.users.find({}, { name: 1, email: 1 })
// 排除age字段
db.users.find({}, { age: 0 })
// 嵌套字段投影
db.users.find({}, { "address.city": 1 })
// 使用$elemMatch投影数组元素
db.users.find(
{ hobbies: { $in: ["读书"] } },
{ hobbies: { $elemMatch: { $eq: "读书" } } }
)
查询选项
javascript
// 限制返回文档数量
db.users.find().limit(5)
// 跳过前3个文档
db.users.find().skip(3)
// 排序 - 1升序,-1降序
db.users.find().sort({ age: -1, name: 1 })
// 统计匹配文档数量
db.users.find({ age: { $gte: 25 } }).count()
// 检查是否存在匹配文档
db.users.findOne({ name: "张三" }) != null
更新操作(Update)
更新操作用于修改现有文档。
更新单个文档
updateOne()
updateOne()方法更新匹配查询的第一个文档:
javascript
// 更新用户的年龄
db.users.updateOne(
{ name: "张三" }, // 查询条件
{ $set: { age: 26 } } // 更新操作
)
// 使用其他更新操作符
db.users.updateOne(
{ name: "张三" },
{
$set: { lastModified: new Date() },
$inc: { loginCount: 1 },
$push: { loginHistory: new Date() }
}
)
更新多个文档
updateMany()
updateMany()方法更新所有匹配的文档:
javascript
// 将所有年龄小于18的用户标记为未成年
db.users.updateMany(
{ age: { $lt: 18 } },
{ $set: { minor: true } }
)
// 批量增加积分
db.users.updateMany(
{ level: "VIP" },
{ $inc: { points: 100 } }
)
替换文档
replaceOne()
replaceOne()方法替换整个文档(除了_id字段):
javascript
// 替换整个用户文档
db.users.replaceOne(
{ name: "张三" },
{
name: "张三丰",
age: 88,
email: "zhangsanfeng@example.com",
status: "legendary"
}
)
更新操作符
字段更新
javascript
// $set - 设置字段值
db.users.updateOne(
{ name: "张三" },
{ $set: { status: "active", lastLogin: new Date() } }
)
// $unset - 删除字段
db.users.updateOne(
{ name: "张三" },
{ $unset: { tempField: "" } }
)
// $rename - 重命名字段
db.users.updateOne(
{ name: "张三" },
{ $rename: { "oldName": "name" } }
)
// $inc - 增加数值
db.users.updateOne(
{ name: "张三" },
{ $inc: { loginCount: 1, points: 10 } }
)
// $mul - 乘以数值
db.users.updateOne(
{ name: "张三" },
{ $mul: { salary: 1.1 } } // 薪资增加10%
)
// $min/$max - 最小值/最大值
db.users.updateOne(
{ name: "张三" },
{ $min: { minScore: 80 }, $max: { maxScore: 100 } }
)
数组更新
javascript
// $push - 添加元素到数组
db.users.updateOne(
{ name: "张三" },
{ $push: { hobbies: "旅行" } }
)
// $addToSet - 添加元素(如果不存在)
db.users.updateOne(
{ name: "张三" },
{ $addToSet: { skills: "MongoDB" } }
)
// $pop - 移除数组首尾元素
db.users.updateOne(
{ name: "张三" },
{ $pop: { hobbies: 1 } } // 移除最后一个
)
// $pull - 移除匹配的数组元素
db.users.updateOne(
{ name: "张三" },
{ $pull: { hobbies: "吸烟" } }
)
// $pullAll - 移除所有匹配的元素
db.users.updateOne(
{ name: "张三" },
{ $pullAll: { hobbies: ["吸烟", "喝酒"] } }
)
// $push with $each - 添加多个元素
db.users.updateOne(
{ name: "张三" },
{ $push: { hobbies: { $each: ["摄影", "徒步"] } } }
)
// $push with $slice - 限制数组长度
db.users.updateOne(
{ name: "张三" },
{
$push: {
recentActivities: {
$each: ["login"],
$slice: -10 // 只保留最后10个活动
}
}
}
)
upsert操作
upsert是指如果文档不存在则插入,如果存在则更新:
javascript
// upsert示例
db.users.updateOne(
{ email: "newuser@example.com" }, // 查询条件
{ $set: { name: "新用户", status: "active" } }, // 更新操作
{ upsert: true } // 如果不存在则插入
)
删除操作(Delete)
删除操作用于从集合中移除文档。
删除单个文档
deleteOne()
deleteOne()方法删除匹配查询的第一个文档:
javascript
// 删除第一个名为"张三"的用户
db.users.deleteOne({ name: "张三" })
// 删除年龄最小的用户
db.users.deleteOne({}, { sort: { age: 1 } })
删除多个文档
deleteMany()
deleteMany()方法删除所有匹配的文档:
javascript
// 删除所有年龄大于60的用户
db.users.deleteMany({ age: { $gt: 60 } })
// 删除所有状态为inactive的用户
db.users.deleteMany({ status: "inactive" })
// 删除所有测试用户
db.users.deleteMany({ email: { $regex: "@test.com$" } })
清空集合
javascript
// 删除集合中的所有文档
db.users.deleteMany({})
// 或者使用drop命令删除整个集合
db.users.drop()
批量操作
MongoDB支持批量操作以提高性能:
javascript
// 初始化批量操作
var bulk = db.users.initializeUnorderedBulkOp();
// 添加多个操作
bulk.insert({ name: "用户1", age: 25 });
bulk.insert({ name: "用户2", age: 30 });
bulk.find({ name: "用户1" }).updateOne({ $set: { status: "active" } });
bulk.find({ name: "用户2" }).removeOne();
// 执行批量操作
bulk.execute();
写关注(Write Concern)
写关注定义了写操作的确认级别:
javascript
// 默认写关注
db.users.insertOne(doc, { writeConcern: { w: 1 } })
// 要求写入到多数节点
db.users.insertOne(doc, { writeConcern: { w: "majority" } })
// 设置写入超时
db.users.insertOne(doc, {
writeConcern: {
w: "majority",
wtimeout: 5000 // 5秒超时
}
})
读关注(Read Concern)
读关注定义了读操作的一致性级别:
javascript
// 本地读关注
db.users.findOne({ name: "张三" }, { readConcern: { level: "local" } })
// 线性化读关注(最强一致性)
db.users.findOne({ name: "张三" }, { readConcern: { level: "linearizable" } })
// 多数读关注
db.users.findOne({ name: "张三" }, { readConcern: { level: "majority" } })
总结
MongoDB的CRUD操作提供了完整的数据管理功能。理解这些操作及其选项对于有效地使用MongoDB至关重要。在实际应用中,应根据具体的业务需求选择合适的操作方法和选项,以获得最佳的性能和数据一致性。