Database References

在本页面

在 MongoDB 中,某些数据经过“非规范化”,或与相关数据一起存储在documents中,以消除对联接的需要。但是,在某些情况下,将相关信息存储在单独的文档中(通常存储在不同的集合或数据库中)是有意义的。

Important

从 3.2 版开始,您可以使用$lookup对同一数据库中的未分片集合执行左外部联接。

有关更多信息和示例,请参见$lookup

本页概述了$lookup管道阶段之前的替代过程。

MongoDB 应用程序使用以下两种方法之一来关联文档:

若要解析 DBRef,您的应用程序必须执行其他查询以返回引用的文档。许多drivers具有帮助程序方法,这些方法自动形成 DBRef 的查询。驱动程序[1]不会自动将 DBRef 解析为文档。

DBRef 提供了一种通用的格式和类型来表示文档之间的关系。如果数据库必须与多个框架和工具进行交互,则 DBRef 格式还提供了表示文档之间链接的通用语义。

除非您有令人信服的理由使用 DBRef,否则请改为使用手动引用。

[1] 一些社区支持的驱动程序可能会有其他行为,并且可能会自动将 DBRef 解析为文档。

Manual References

Background

使用手动引用是在另一个文档中包含一个document's _id字段的一种做法。然后,应用程序可以根据需要发出第二个查询来解析引用的字段。

Process

考虑以下操作,使用第一个文档的_id字段作为第二个文档的参考来插入两个文档:

original_id = ObjectId()

db.places.insert({
    "_id": original_id,
    "name": "Broadway Center",
    "url": "bc.example.net"
})

db.people.insert({
    "name": "Erin",
    "places_id": original_id,
    "url":  "bc.example.net/Erin"
})

然后,当查询从people集合返回文档时,您可以根据需要再次查询places集合中places_id字段引用的文档。

Use

对于几乎要在两个文档之间存储关系的每种情况,请使用manual references。引用很容易创建,您的应用程序可以根据需要解析引用。

手动链接的唯一限制是这些引用不传达数据库和集合名称。如果单个集合中的文档与多个集合中的文档相关,则可能需要考虑使用 DBRef。

DBRefs

Background

DBRef 是表示document的约定,而不是特定的引用类型。除了_id字段中的值之外,它们还包括集合的名称,在某些情况下还包括数据库的名称。

Format

DBRef 具有以下字段:

包含引用文档所在的数据库的名称。

仅某些驱动程序支持$db参考。

Example

DBRef 文档类似于以下文档:

{ "$ref" : <value>, "$id" : <value>, "$db" : <value> }

考虑来自在creator字段中存储 DBRef 的集合中的文档:

{
"_id" : ObjectId("5126bbf64aed4daf9e2ab771"),
// .. application fields
"creator" : {
"$ref" : "creators",
"$id" : ObjectId("5126bc054aed4daf9e2ab772"),
"$db" : "users"
}
}

在此示例中,DBRef 指向users数据库的creators集合中的文档,该文档的_id字段中具有ObjectId("5126bc054aed4daf9e2ab772")

Note

DBRef 中字段的 Sequences 很重要,使用 DBRef 时必须使用上述 Sequences。

DBRef 的驱动程序支持

Driver DBRef Support Notes
C Not Supported 您可以手动遍历引用。
C++ Not Supported 您可以手动遍历引用。
C# Supported 请参阅C#驱动程序页面以获取更多信息。
Haskell Not Supported 您可以手动遍历引用。
Java Supported 请参阅Java 驱动程序页面以获取更多信息。
Node.js Supported 请参阅Node.js 驱动程序页面以获取更多信息。
Perl Supported 请参阅Perl 驱动程序页面以获取更多信息。
PHP Not Supported 您可以手动遍历引用。
Python Supported 请参阅PyMongo 驱动程序页面以获取更多信息。
Ruby Supported 请参阅Ruby 驱动程序页面以获取更多信息。
Scala Not Supported 您可以手动遍历引用。

Use

在大多数情况下,您应该使用manual reference方法来连接两个或更多相关文档。但是,如果需要引用多个集合中的文档,请考虑使用 DBRef。

首页