MongoDB 文档链接

MongoDBMongoDBBeginner
立即练习

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

介绍

在本实验中,你将学习如何在 MongoDB 文档之间建立关系,包括创建文档引用、更新相关数据、查询链接文档、移除文档链接以及确保数据完整性。实验涵盖了处理 MongoDB 关系的基本技术,例如使用 $lookup 聚合阶段来连接集合,以及跨相关集合更新文档。通过本实验,你将深入了解如何在 MongoDB 数据库中管理关系。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL mongodb(("MongoDB")) -.-> mongodb/RelationshipsGroup(["Relationships"]) mongodb(("MongoDB")) -.-> mongodb/QueryOperationsGroup(["Query Operations"]) mongodb(("MongoDB")) -.-> mongodb/AggregationOperationsGroup(["Aggregation Operations"]) mongodb(("MongoDB")) -.-> mongodb/BasicOperationsGroup(["Basic Operations"]) mongodb/BasicOperationsGroup -.-> mongodb/insert_document("Insert Document") mongodb/BasicOperationsGroup -.-> mongodb/update_document("Update Document") mongodb/BasicOperationsGroup -.-> mongodb/delete_document("Delete Document") mongodb/QueryOperationsGroup -.-> mongodb/find_documents("Find Documents") mongodb/QueryOperationsGroup -.-> mongodb/query_with_conditions("Query with Conditions") mongodb/QueryOperationsGroup -.-> mongodb/project_fields("Project Fields") mongodb/AggregationOperationsGroup -.-> mongodb/aggregate_group_totals("Aggregate Group Totals") mongodb/RelationshipsGroup -.-> mongodb/create_document_references("Create Document References") mongodb/RelationshipsGroup -.-> mongodb/link_related_documents("Link Related Documents") subgraph Lab Skills mongodb/insert_document -.-> lab-422087{{"MongoDB 文档链接"}} mongodb/update_document -.-> lab-422087{{"MongoDB 文档链接"}} mongodb/delete_document -.-> lab-422087{{"MongoDB 文档链接"}} mongodb/find_documents -.-> lab-422087{{"MongoDB 文档链接"}} mongodb/query_with_conditions -.-> lab-422087{{"MongoDB 文档链接"}} mongodb/project_fields -.-> lab-422087{{"MongoDB 文档链接"}} mongodb/aggregate_group_totals -.-> lab-422087{{"MongoDB 文档链接"}} mongodb/create_document_references -.-> lab-422087{{"MongoDB 文档链接"}} mongodb/link_related_documents -.-> lab-422087{{"MongoDB 文档链接"}} end

创建文档引用

在这一步骤中,你将学习如何在 MongoDB 中创建文档引用,这是在不同集合之间建立关系的基本技术。

首先,启动 MongoDB shell:

mongosh

我们将创建两个集合来演示文档引用:authorsbooks。这是一个常见的场景,其中书籍与其作者相关联。

创建 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 中创建文档引用,这是在不同集合之间建立关系的基础技术。你创建了两个集合,authorsbooks,并使用 author_id 字段将书籍与其作者关联起来。你还学习了如何使用 $lookup 聚合阶段查询链接的文档。此外,你探索了如何更新相关文档、查询链接文档、移除文档链接,以及在处理 MongoDB 中的文档引用时确保数据完整性。