介绍
在本实验中,你将学习如何在 MongoDB 文档之间建立关系,包括创建文档引用、更新相关数据、查询链接文档、移除文档链接以及确保数据完整性。实验涵盖了处理 MongoDB 关系的基本技术,例如使用 $lookup
聚合阶段来连接集合,以及跨相关集合更新文档。通过本实验,你将深入了解如何在 MongoDB 数据库中管理关系。
在本实验中,你将学习如何在 MongoDB 文档之间建立关系,包括创建文档引用、更新相关数据、查询链接文档、移除文档链接以及确保数据完整性。实验涵盖了处理 MongoDB 关系的基本技术,例如使用 $lookup
聚合阶段来连接集合,以及跨相关集合更新文档。通过本实验,你将深入了解如何在 MongoDB 数据库中管理关系。
在这一步骤中,你将学习如何在 MongoDB 中创建文档引用,这是在不同集合之间建立关系的基本技术。
首先,启动 MongoDB shell:
mongosh
我们将创建两个集合来演示文档引用:authors
和 books
。这是一个常见的场景,其中书籍与其作者相关联。
创建 authors
集合:
use library_database
db.authors.insertMany([
{
_id: ObjectId("660a1f5c9b8f8b1234567890"),
name: "Jane Austen",
nationality: "British"
},
{
_id: ObjectId("660a1f5c9b8f8b1234567891"),
name: "George Orwell",
nationality: "British"
}
])
示例输出:
{
acknowledged: true,
insertedIds: {
'0': ObjectId("660a1f5c9b8f8b1234567890"),
'1': ObjectId("660a1f5c9b8f8b1234567891")
}
}
现在,创建 books
集合并引用作者:
db.books.insertMany([
{
title: "Pride and Prejudice",
author_id: ObjectId("660a1f5c9b8f8b1234567890"),
year: 1813
},
{
title: "1984",
author_id: ObjectId("660a1f5c9b8f8b1234567891"),
year: 1949
}
])
示例输出:
{
acknowledged: true,
insertedIds: {
'0': ObjectId("660b2a1c9b8f8b1234567892"),
'1': ObjectId("660b2a1c9b8f8b1234567893")
}
}
通过查询书籍及其作者详细信息来验证引用:
db.books.aggregate([
{
$lookup: {
from: "authors",
localField: "author_id",
foreignField: "_id",
as: "author_details"
}
}
])
这展示了如何在 MongoDB 中创建文档引用。我们使用 author_id
字段将书籍与其作者关联起来,该字段包含对应作者的 ObjectId。
在这一步骤中,你将学习如何在 MongoDB 中更新相关文档,基于我们在上一步中创建的文档引用。
首先,确保你已连接到 MongoDB shell 并使用 library_database
数据库:
mongosh
use library_database
让我们更新一位作者的信息。我们将修改 Jane Austen 的详细信息:
db.authors.updateOne(
{ _id: ObjectId("660a1f5c9b8f8b1234567890") },
{
$set: {
birth_year: 1775,
notable_works: ["Pride and Prejudice", "Sense and Sensibility"]
}
}
)
示例输出:
{
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 1
}
现在,让我们在保持引用关系的同时更新一本书的详细信息:
db.books.updateOne(
{ title: "Pride and Prejudice" },
{
$set: {
genre: "Romance",
pages: 432,
rating: 4.5
}
}
)
示例输出:
{
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 1
}
通过查询完整详细信息来验证更新:
db.authors.findOne({ name: "Jane Austen" })
db.books.findOne({ title: "Pride and Prejudice" })
这展示了如何在保持引用关系的同时更新相关文档。$set
操作符允许你添加或修改特定字段,而无需替换整个文档。
在这一步骤中,你将学习如何使用 MongoDB 的 $lookup
聚合管道阶段来查询链接文档的高级技术。
首先,确保你已连接到 MongoDB shell:
mongosh
use library_database
让我们执行一个简单的 $lookup
操作,将书籍与其作者关联起来:
db.books.aggregate([
{
$lookup: {
from: "authors",
localField: "author_id",
foreignField: "_id",
as: "author_details"
}
}
])
现在,让我们创建一个更复杂的查询,按作者国籍过滤书籍:
db.books.aggregate([
{
$lookup: {
from: "authors",
localField: "author_id",
foreignField: "_id",
as: "author_details"
}
},
{
$match: {
"author_details.nationality": "British"
}
},
{
$project: {
title: 1,
year: 1,
"author_name": { $arrayElemAt: ["$author_details.name", 0] }
}
}
])
让我们创建另一个查询,查找 1900 年后出版的书籍:
db.books.aggregate([
{
$lookup: {
from: "authors",
localField: "author_id",
foreignField: "_id",
as: "author_details"
}
},
{
$match: {
year: { $gt: 1900 }
}
},
{
$project: {
title: 1,
year: 1,
"author_name": { $arrayElemAt: ["$author_details.name", 0] }
}
}
])
这些查询展示了使用 MongoDB 聚合框架查询和组合链接文档的不同方法。
在这一步骤中,你将学习如何移除文档链接并管理 MongoDB 中的相关文档。
首先,确保你已连接到 MongoDB shell:
mongosh
use library_database
让我们从删除特定书籍开始,同时保留作者信息:
db.books.deleteOne({ title: "1984" })
示例输出:
{ acknowledged: true, deletedCount: 1 }
现在,让我们通过多步骤流程删除一位作者及其所有相关书籍:
// 首先,查找作者的 ID
const authorToRemove = db.authors.findOne({ name: "George Orwell" })
// 删除该作者的所有书籍
db.books.deleteMany({ author_id: authorToRemove._id })
// 然后删除作者
db.authors.deleteOne({ _id: authorToRemove._id })
让我们通过添加状态字段来演示软删除方法:
db.books.updateOne(
{ title: "Pride and Prejudice" },
{
$set: {
status: "archived",
archived_date: new Date()
}
}
)
查询仅包含活跃书籍:
db.books.find({
$or: [
{ status: { $exists: false } },
{ status: { $ne: "archived" } }
]
})
这些方法展示了管理文档链接和移除相关文档的不同策略。
在这一步骤中,你将学习确保 MongoDB 文档关系中的数据完整性的技术。
首先,确保你已连接到 MongoDB shell:
mongosh
use library_database
为 authors
集合创建验证规则:
db.createCollection("authors", {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["name", "nationality"],
properties: {
name: {
bsonType: "string",
description: "must be a string and is required"
},
nationality: {
bsonType: "string",
description: "must be a string and is required"
},
birth_year: {
bsonType: "int",
minimum: 1500,
maximum: 2023,
description: "must be an integer between 1500 and 2023"
}
}
}
}
})
让我们创建一个函数来检查孤立的引用:
function checkOrphanedReferences() {
const orphanedBooks = db.books.aggregate([
{
$lookup: {
from: "authors",
localField: "author_id",
foreignField: "_id",
as: "author_exists"
}
},
{
$match: {
author_exists: { $size: 0 }
}
}
]).toArray()
print("Orphaned Books:", orphanedBooks.length)
return orphanedBooks
}
checkOrphanedReferences()
为书籍文档创建数据完整性检查:
function validateBookDocuments() {
const invalidBooks = db.books.find({
$or: [
{ title: { $not: { $type: "string" } } },
{ year: { $not: { $type: "int" } } },
{ year: { $lt: 0 } }
]
}).toArray()
print("Invalid Books:", invalidBooks.length)
return invalidBooks
}
validateBookDocuments()
演示引用完整性检查:
function checkReferentialIntegrity() {
const authorIds = db.authors.distinct("_id")
const bookAuthorIds = db.books.distinct("author_id")
const missingAuthors = bookAuthorIds.filter(
id => !authorIds.some(authorId => authorId.equals(id))
)
print("Missing Author References:", missingAuthors.length)
return missingAuthors
}
checkReferentialIntegrity()
在本实验中,你学习了如何在 MongoDB 中创建文档引用,这是在不同集合之间建立关系的基础技术。你创建了两个集合,authors
和 books
,并使用 author_id
字段将书籍与其作者关联起来。你还学习了如何使用 $lookup
聚合阶段查询链接的文档。此外,你探索了如何更新相关文档、查询链接文档、移除文档链接,以及在处理 MongoDB 中的文档引用时确保数据完整性。