mongodb - 如何在 MongoDB 中使用文档和集合之间的关系

标签 mongodb database-design mongoose database-schema database

我的集合中有以下文档objects_parameters:

{
    "_id" : ObjectId("5922ef07470e6cc50c3c987d"),
    "object_id" : "5922ef07470e6cc50c3c987c",
    "parameter_id" : "5922e986470e6cc60c3c987e",
    "value" : "5922e986470e6cc60c3c987e"
}

如您所见,value 字段包含(引用)parameters 集合中另一个文档的 _id

如何使用该 value 字段绑定(bind)这两个集合?

最佳答案

有两种方法可以做到这一点,使用 Manual References ,您已经在这样做,或者使用 DBRefs ,这只是表示文档的约定,但受 MongoDB 驱动程序支持,如 this example 中所示。 .

但是,手动引用本身没有任何类型的特殊支持,因此您有两种选择来填充这些引用,我猜这就是您绑定(bind)这两个集合的意思。

  • 第一个是直接从应用程序使用 MongoDB 驱动程序手动执行此操作,即查询一个或多个父文档、读取它们的引用并查询其他文档。然后,您可以将所有这些文档合并在一起以返回单个结果。

  • 第二种选择,我认为更好,是依靠您选择的库来为您做到这一点。我建议看一下 Mongoose如果您使用 Node.js。

    Mongoose 让您可以轻松定义文档之间的引用并轻松填充它们,如您所见 official docs .

我可能会选择手动引用,因为我认为它更简洁,并且不需要在数据库中存储与模式相关的信息(这占用空间),但这可能是个人喜好的问题,尽管这也是推荐的选项:

Unless you have a compelling reason to use DBRefs, use manual references instead.

DBRef 示例:

主要区别之一是,使用DBRefs时,关系的所有信息都存储在文档本身中,因此您可能有一个posts集合,其文档看起来像这样:

{
    "_id" : ObjectId("5126bbf64aed4daf9e2ab771"),
    "text" : ...,
    "author" : {
        "$ref" : "authors",
        "$id" : ObjectId("5126bc054aed4daf9e2ab772"),
        "$db" : "users"
    }
}

只需查看该文档,您就知道作者数据所在的位置。您可以看到它存储在名为 users 的数据库中,位于名为 authors 的集合中,其 _id5126bc054aed4daf9e2ab772.

手动引用示例:

但是,如果您使用手动引用,则同一文档将如下所示:

{
    "_id" : ObjectId("5126bbf64aed4daf9e2ab771"),
    "text" : ...,
    "author" : ObjectId("5126bc054aed4daf9e2ab772")
}

因此,仅通过查看该文档,您无法知道在哪里可以找到填充 author 字段所需的信息。该信息现在将驻留在应用程序级别的 Mongoose 架构定义中,特别是如果您选择使用此工具。

性能说明:

在这两种情况下,您都将执行额外的请求来填充这些引用,因此 DBRefs 不会为您提供比手动引用任何类型的性能增益。

嵌入/反规范化注意:

如果做得明智的话,嵌入文档并在需要时为其建立索引将为您带来更多性能提升,并且 guarantees you have atomic operations, as MongoDB offers single-document atomicity .

关于mongodb - 如何在 MongoDB 中使用文档和集合之间的关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44114967/

相关文章:

node.js - Mongoose中间件访问其他集合

python - mongoengine - 使用 QuerySet 作为 ReferenceField

javascript - 如何执行find中的函数或将数据保存在变量中?

javascript - for 循环内的 async.waterfall 逃脱了 for 循环

mysql - 每行值数量有限的数据库设计

javascript - 如何使用 MongoDB/Mongoose.js 查询类似 OR/AND 的条件?

database - 在数据库列中存储分隔列表真的那么糟糕吗?

sql - 陷入数据库设计问题

javascript - MongoDB 按日期查询并按距离排序(Mongoose + Express App)

mongodb - 使用 Typescript 在 Mongoose 中缺少子文档方法