管理 MongoDB 嵌入式文档

MongoDBMongoDBBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

介绍

在本实验中,你将学习如何有效地管理 MongoDB 中的嵌入式文档(embedded documents)。实验涵盖了一系列技术,包括创建嵌套文档、更新嵌套字段、删除嵌套元素、查询嵌套数据以及验证文档结构。这些技能对于处理 MongoDB 中复杂的层次化数据至关重要,能够帮助你构建健壮且高效的应用程序。通过逐步的指导,你将全面掌握在 MongoDB 项目中管理嵌入式文档的技巧。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL mongodb(("MongoDB")) -.-> mongodb/BasicOperationsGroup(["Basic Operations"]) mongodb(("MongoDB")) -.-> mongodb/DataTypesGroup(["Data Types"]) mongodb(("MongoDB")) -.-> mongodb/ArrayandEmbeddedDocumentsGroup(["Array and Embedded Documents"]) mongodb(("MongoDB")) -.-> mongodb/QueryOperationsGroup(["Query Operations"]) mongodb/BasicOperationsGroup -.-> mongodb/create_database_collection("Create Database and Collection") mongodb/BasicOperationsGroup -.-> mongodb/insert_document("Insert Document") mongodb/BasicOperationsGroup -.-> mongodb/update_document("Update Document") mongodb/QueryOperationsGroup -.-> mongodb/query_with_conditions("Query with Conditions") mongodb/DataTypesGroup -.-> mongodb/use_string_data_types("Use String Data Types") mongodb/DataTypesGroup -.-> mongodb/work_with_array_data_types("Work with Array Data Types") mongodb/DataTypesGroup -.-> mongodb/manage_array_elements("Manage Array Elements") mongodb/ArrayandEmbeddedDocumentsGroup -.-> mongodb/create_embedded_documents("Create Embedded Documents") mongodb/ArrayandEmbeddedDocumentsGroup -.-> mongodb/query_embedded_documents("Query Embedded Documents") subgraph Lab Skills mongodb/create_database_collection -.-> lab-422088{{"管理 MongoDB 嵌入式文档"}} mongodb/insert_document -.-> lab-422088{{"管理 MongoDB 嵌入式文档"}} mongodb/update_document -.-> lab-422088{{"管理 MongoDB 嵌入式文档"}} mongodb/query_with_conditions -.-> lab-422088{{"管理 MongoDB 嵌入式文档"}} mongodb/use_string_data_types -.-> lab-422088{{"管理 MongoDB 嵌入式文档"}} mongodb/work_with_array_data_types -.-> lab-422088{{"管理 MongoDB 嵌入式文档"}} mongodb/manage_array_elements -.-> lab-422088{{"管理 MongoDB 嵌入式文档"}} mongodb/create_embedded_documents -.-> lab-422088{{"管理 MongoDB 嵌入式文档"}} mongodb/query_embedded_documents -.-> lab-422088{{"管理 MongoDB 嵌入式文档"}} end

创建嵌套文档

在这一步骤中,你将学习如何在 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 是一个嵌套文档,包含 namecontact 子文档
  • 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 面向文档的数据模型在处理复杂的嵌套数据结构时的灵活性和强大功能。