介绍
在本实验中,你将学习如何在 MongoDB 集合中更新文档。你将首先使用 updateOne() 方法修改单个文档。然后,你将学习使用 updateMany() 方法一次修改多个文档。你还将使用各种更新操作符,如 $set、$inc 和 $unset,来执行特定的修改。最后,你将探索 upsert 选项,该选项允许你更新现有文档或在文档不存在时创建新文档。本实验提供了一种实用的、动手实践的方法来掌握 MongoDB 中基本的数据操作技能。
在本实验中,你将学习如何在 MongoDB 集合中更新文档。你将首先使用 updateOne() 方法修改单个文档。然后,你将学习使用 updateMany() 方法一次修改多个文档。你还将使用各种更新操作符,如 $set、$inc 和 $unset,来执行特定的修改。最后,你将探索 upsert 选项,该选项允许你更新现有文档或在文档不存在时创建新文档。本实验提供了一种实用的、动手实践的方法来掌握 MongoDB 中基本的数据操作技能。
updateOne 更新单个文档在本步骤中,你将学习如何在 MongoDB 集合中修改单个文档。我们将使用 updateOne() 方法和 $set 操作符来更改特定文档中的字段值。
首先,打开 MongoDB Shell 以便与你的数据库进行交互。
mongosh
进入 shell 后,切换到为你准备好的 mylab_database。
use mylab_database
让我们查看 books 集合中的当前文档。.pretty() 方法会格式化输出,使其更易读。
db.books.find().pretty();
你应该会看到三个初始的图书文档。_id 值在你自己的环境中将是唯一的。
[
{
_id: ObjectId("..."),
title: 'JavaScript Fundamentals',
author: 'Mike Johnson',
year: 2022,
pages: 350
},
{
_id: ObjectId("..."),
title: 'Python Deep Dive',
author: 'Sarah Williams',
year: 2021,
pages: 450
},
{
_id: ObjectId("..."),
title: 'Machine Learning Basics',
author: 'John Doe',
year: 2020,
price: 39.99
}
]
现在,让我们将 "JavaScript Fundamentals" 这本书的出版年份更新为 2023。
db.books.updateOne(
{ title: "JavaScript Fundamentals" },
{ $set: { year: 2023 } }
);
让我们分解一下这个命令:
updateOne(): 此方法查找第一个匹配筛选条件的文档并更新它。{ title: "JavaScript Fundamentals" }: 这是筛选文档。它告诉 MongoDB 查找 title 字段为 "JavaScript Fundamentals" 的文档。{ $set: { year: 2023 } }: 这是更新文档。$set 操作符将 year 字段的值替换为 2023。该命令会返回一个结果对象,确认操作已执行。
{
"acknowledged": true,
"insertedId": null,
"matchedCount": 1,
"modifiedCount": 1,
"upsertedCount": 0
}
matchedCount: 1 表明有一个文档匹配了我们的筛选条件,而 modifiedCount: 1 表明有一个文档已成功更新。
为了验证更改,再次查找该文档。
db.books.findOne({ title: "JavaScript Fundamentals" });
输出将显示更新后的文档,包含新的年份。
{
_id: ObjectId("..."),
title: 'JavaScript Fundamentals',
author: 'Mike Johnson',
year: 2023,
pages: 350
}
updateMany 更新多个文档有时你需要一次性更新多个文档。为此,MongoDB 提供了 updateMany() 方法。在本步骤中,你将为所有在特定年份之前出版的书籍添加一个新字段。
让我们为所有在 2022 年之前出版的书籍添加一个 status 字段,值为 "Classic"。
db.books.updateMany({ year: { $lt: 2022 } }, { $set: { status: "Classic" } });
以下是对该命令的解释:
updateMany(): 此方法更新所有匹配指定筛选条件的文档。{ year: { $lt: 2022 } }: 此筛选器选择 year 小于 2022 的文档。$lt 操作符代表“小于”(less than)。{ $set: { status: "Classic" } }: 此更新文档向所有匹配的文档添加一个新字段 status,其值为 "Classic"。输出将显示匹配和修改了多少文档。在本例中,有两本书是在 2022 年之前出版的。
{
"acknowledged": true,
"insertedId": null,
"matchedCount": 2,
"modifiedCount": 2,
"upsertedCount": 0
}
为了验证两个文档是否都已更新,你可以查询所有 status 为 "Classic" 的书籍。
db.books.find({ status: "Classic" }).pretty();
你将看到这两本书现在都包含了 status 字段。
[
{
_id: ObjectId("..."),
title: 'Python Deep Dive',
author: 'Sarah Williams',
year: 2021,
pages: 450,
status: 'Classic'
},
{
_id: ObjectId("..."),
title: 'Machine Learning Basics',
author: 'John Doe',
year: 2020,
price: 39.99,
status: 'Classic'
}
]
$inc 和 $unsetMongoDB 提供了各种操作符以支持不同类型的更新。在本步骤中,你将学习使用 $inc 来修改数值,以及使用 $unset 来从文档中移除字段。
首先,让我们使用 $inc 操作符将 "Python Deep Dive" 这本书的页数增加 50。$inc 操作符会按指定值递增一个字段。
db.books.updateOne({ title: "Python Deep Dive" }, { $inc: { pages: 50 } });
为了确认更改,请检索该文档。
db.books.findOne({ title: "Python Deep Dive" });
此时 pages 字段应为 500(450 + 50)。
{
_id: ObjectId("..."),
title: 'Python Deep Dive',
author: 'Sarah Williams',
year: 2021,
pages: 500,
status: 'Classic'
}
接下来,让我们从 "Machine Learning Basics" 文档中移除 price 字段。$unset 操作符会删除指定的字段。提供给 $unset 的值(在此例中为 "")无关紧要,可以是任何值。
db.books.updateOne(
{ title: "Machine Learning Basics" },
{ $unset: { price: "" } }
);
让我们验证一下 price 字段是否已被移除。
db.books.findOne({ title: "Machine Learning Basics" });
输出将显示该文档不再包含 price 字段。
{
_id: ObjectId("..."),
title: 'Machine Learning Basics',
author: 'John Doe',
year: 2020,
status: 'Classic'
}
upsert 创建文档"Upsert" 是一种特殊的更新操作,如果文档存在,则对其进行更新;如果文档不存在,则插入一个新文档。这有助于避免单独的“检查后插入”逻辑,并确保数据库操作的原子性。在以下场景中,Upsert 特别有用:
你可以通过向更新命令添加 upsert: true 选项来启用此行为。
我们尝试添加一本新书 "Cloud Computing Essentials"。由于这本书不存在于我们的集合中,upsert 操作将创建它。
db.books.updateOne(
{ title: "Cloud Computing Essentials" },
{ $set: { author: "David Lee", year: 2023, pages: 300 } },
{ upsert: true }
);
该命令包含三个部分:
{ title: "Cloud Computing Essentials" }{ $set: { ... } }{ upsert: true }由于没有文档匹配筛选条件,因此创建了一个新文档。结果对象通过包含 upsertedId 来反映这一点。
{
acknowledged: true,
matchedCount: 0,
modifiedCount: 0,
upsertedCount: 1,
upsertedId: ObjectId("...")
}
现在,我们再次运行相同的命令。这次,MongoDB 将找到我们刚刚创建的文档并对其进行更新。
db.books.updateOne(
{ title: "Cloud Computing Essentials" },
{ $set: { author: "David Lee", year: 2023, pages: 300 } },
{ upsert: true }
);
结果现在显示 matchedCount: 1。由于我们设置的数据与现有数据相同,modifiedCount 为 0。如果我们更改了某个值,modifiedCount 将为 1。
{
"acknowledged": true,
"insertedId": null,
"matchedCount": 1,
"modifiedCount": 0,
"upsertedCount": 0
}
你可以验证新书是否已存在于集合中。
db.books.findOne({ title: "Cloud Computing Essentials" });
输出将显示新创建的文档。
{
_id: ObjectId("..."),
title: 'Cloud Computing Essentials',
author: 'David Lee',
year: 2023,
pages: 300
}
完成后,你可以退出 MongoDB Shell。
exit;
在本实验中,你学习了在 MongoDB 中更新文档的基本技术。你练习了使用 updateOne 修改单个文档,以及使用 updateMany 修改多个文档。你还探索了强大的更新操作符,包括用于更改字段值的 $set,用于递增数字的 $inc,以及用于移除字段的 $unset。最后,你学习了如何使用 upsert 选项在文档不存在时创建它。这些技能是管理和维护任何 MongoDB 应用程序中数据的基本功。