介绍
在本实验中,你将学习如何有效地管理 MongoDB 中的嵌入式文档(embedded documents)。实验涵盖了一系列技术,包括创建嵌套文档、更新嵌套字段、删除嵌套元素、查询嵌套数据以及验证文档结构。这些技能对于处理 MongoDB 中复杂的层次化数据至关重要,能够帮助你构建健壮且高效的应用程序。通过逐步的指导,你将全面掌握在 MongoDB 项目中管理嵌入式文档的技巧。
在本实验中,你将学习如何有效地管理 MongoDB 中的嵌入式文档(embedded documents)。实验涵盖了一系列技术,包括创建嵌套文档、更新嵌套字段、删除嵌套元素、查询嵌套数据以及验证文档结构。这些技能对于处理 MongoDB 中复杂的层次化数据至关重要,能够帮助你构建健壮且高效的应用程序。通过逐步的指导,你将全面掌握在 MongoDB 项目中管理嵌入式文档的技巧。
在这一步骤中,你将学习如何在 MongoDB 中创建嵌套文档(nested documents),这允许你在单个文档中存储复杂的层次化数据。嵌套文档非常适合表示关系和结构化信息。
首先,启动 MongoDB shell:
mongosh
接下来,为我们的示例创建一个数据库:
use bookstore
我们将创建一个名为 books
的集合,其中包含表示书籍详细信息的嵌套文档:
db.books.insertOne({
title: "Advanced MongoDB",
author: {
name: "Jane Smith",
contact: {
email: "[email protected]",
phone: "+1-555-123-4567"
}
},
published: {
year: 2023,
publisher: "Tech Publications"
},
chapters: [
{ number: 1, title: "Introduction to Nested Documents" },
{ number: 2, title: "Advanced Document Structures" }
]
})
让我们分解这个文档:
title
author
是一个嵌套文档,包含 name
和 contact
子文档published
是另一个嵌套文档,包含出版信息chapters
是一个嵌套文档数组,表示书籍章节要查看我们刚刚创建的文档,可以使用:
db.books.find()
示例输出:
[
{
_id: ObjectId("..."),
title: 'Advanced MongoDB',
author: {
name: 'Jane Smith',
contact: {
email: '[email protected]',
phone: '+1-555-123-4567'
}
},
published: {
year: 2023,
publisher: 'Tech Publications'
},
chapters: [
{ number: 1, title: 'Introduction to Nested Documents' },
{ number: 2, title: 'Advanced Document Structures' }
]
}
]
在这一步骤中,你将学习如何更新 MongoDB 文档中的嵌套字段。基于上一步的内容,我们将使用之前创建的书籍文档来演示嵌套文档的各种更新技术。
首先,确保你已进入 MongoDB shell:
mongosh
切换到 bookstore
数据库:
use bookstore
让我们使用 $set
操作符更新作者的联系信息:
db.books.updateOne(
{ title: "Advanced MongoDB" },
{ $set: {
"author.contact.phone": "+1-888-999-0000",
"author.contact.website": "www.janesmith.com"
} }
)
点符号 "author.contact.phone"
允许我们精确地定位嵌套字段。让我们验证更新结果:
db.books.find({ title: "Advanced MongoDB" })
接下来,我们更新一个嵌套数组。我们将向 chapters
数组中添加一个新章节:
db.books.updateOne(
{ title: "Advanced MongoDB" },
{ $push: {
chapters: {
number: 3,
title: "MongoDB Advanced Techniques"
}
} }
)
$push
操作符用于向数组中添加新元素。让我们验证更新结果:
db.books.find({ title: "Advanced MongoDB" })
我们还可以使用位置操作符 $
更新特定的嵌套数组元素。让我们更新第一个章节:
db.books.updateOne(
{ title: "Advanced MongoDB", "chapters.number": 1 },
{ $set: {
"chapters.$.title": "Introduction to Nested Documents (Revised)"
} }
)
示例输出将显示更新后的文档,其中包含修改的嵌套字段和新增的章节。
在这一步骤中,你将学习如何使用各种操作符从 MongoDB 文档中删除嵌套元素。我们将继续使用之前步骤中的书籍文档。
首先,确保你已进入 MongoDB shell:
mongosh
切换到 bookstore
数据库:
use bookstore
让我们使用 $unset
操作符从嵌套的联系信息中删除特定字段:
db.books.updateOne(
{ title: "Advanced MongoDB" },
{ $unset: { "author.contact.website": "" } }
)
$unset
操作符会完全删除指定的字段。让我们验证更新结果:
db.books.find({ title: "Advanced MongoDB" })
接下来,我们使用 $pull
操作符从 chapters
数组中删除特定元素:
db.books.updateOne(
{ title: "Advanced MongoDB" },
{ $pull: {
chapters: { number: 3 }
} }
)
$pull
操作符会从数组中删除所有匹配的元素。让我们验证结果:
db.books.find({ title: "Advanced MongoDB" })
我们还可以删除整个嵌套的 contact
对象:
db.books.updateOne(
{ title: "Advanced MongoDB" },
{ $unset: { "author.contact": "" } }
)
示例输出将显示删除了嵌套元素后的文档。
在这一步骤中,你将学习如何查询 MongoDB 中的嵌套文档和数组。我们将探索不同的技术来过滤和检索特定的嵌套数据。
首先,让我们重置数据库并插入一些示例数据以演示查询:
mongosh
切换到 bookstore
数据库:
use bookstore
让我们插入多个具有嵌套结构的书籍:
db.books.insertMany([
{
title: "MongoDB Essentials",
author: {
name: "John Doe",
experience: { years: 5, specialization: "Database Design" }
},
tags: ["beginner", "database", "nosql"],
chapters: [
{ number: 1, title: "Introduction", pages: 25 },
{ number: 2, title: "Advanced Concepts", pages: 45 }
]
},
{
title: "Advanced Database Techniques",
author: {
name: "Jane Smith",
experience: { years: 8, specialization: "Distributed Systems" }
},
tags: ["advanced", "distributed", "nosql"],
chapters: [
{ number: 1, title: "System Design", pages: 35 },
{ number: 2, title: "Performance Optimization", pages: 55 }
]
}
])
通过嵌套字段查询书籍:
db.books.find({ "author.name": "John Doe" })
使用点符号查询嵌套对象:
db.books.find({ "author.experience.specialization": "Database Design" })
使用数组包含查询:
db.books.find({ tags: "nosql" })
查询嵌套数组元素:
db.books.find({ "chapters.pages": { $gt: 40 } })
$gt
操作符表示“大于”,因此这条查询会找到章节页数超过 40 页的书籍。
结合嵌套对象和数组条件的复杂查询:
db.books.find({
"author.experience.years": { $gte: 5 },
tags: "advanced"
})
这条查询会找到作者经验超过 5 年且标签为 "advanced"
的书籍。
在这一步骤中,你将学习如何使用 JSON Schema 验证在 MongoDB 中验证文档结构。这可以确保你的文档保持一致且可预测的结构。
首先,启动 MongoDB shell:
mongosh
切换到 bookstore
数据库:
use bookstore
我们将创建一个带有 JSON Schema 验证器的新集合:
db.createCollection("courses", {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["title", "instructor", "duration", "topics"],
properties: {
title: {
bsonType: "string",
description: "must be a string and is required"
},
instructor: {
bsonType: "object",
required: ["name", "email"],
properties: {
name: {
bsonType: "string",
description: "must be a string and is required"
},
email: {
bsonType: "string",
pattern: "^.+@.+$",
description: "must be a valid email address"
}
}
},
duration: {
bsonType: "int",
minimum: 1,
maximum: 100,
description: "must be an integer between 1 and 100"
},
topics: {
bsonType: "array",
minItems: 1,
items: {
bsonType: "string"
},
description: "must be an array of strings with at least one item"
}
}
}
}
})
让我们尝试插入一个有效的文档:
db.courses.insertOne({
title: "MongoDB Advanced Techniques",
instructor: {
name: "Jane Smith",
email: "[email protected]"
},
duration: 40,
topics: ["Nested Documents", "Schema Validation"]
})
现在,让我们尝试插入一个会被拒绝的无效文档:
db.courses.insertOne({
title: "Invalid Course",
instructor: {
name: 123, // 无效:应为字符串
email: "invalid-email" // 无效的电子邮件格式
},
duration: 200, // 超出范围
topics: [] // 空的 topics 数组
})
由于验证规则,此插入操作将失败。
要查看集合的验证规则,可以使用:
db.getCollectionInfos({ name: "courses" })
示例输出将显示 JSON Schema 验证配置。
在本实验中,你将学习如何管理 MongoDB 的嵌入式文档。首先,你将创建嵌套文档,这允许你在单个文档中存储复杂的层次化数据。这对于表示关系和结构化信息非常强大。接下来,你将更新嵌套字段、删除嵌套元素、查询嵌套数据以及验证文档结构。这些技术展示了 MongoDB 面向文档的数据模型在处理复杂的嵌套数据结构时的灵活性和强大功能。