Database References
在本页面
在 MongoDB 中,某些数据经过“非规范化”,或与相关数据一起存储在documents中,以消除对联接的需要。但是,在某些情况下,将相关信息存储在单独的文档中(通常存储在不同的集合或数据库中)是有意义的。
本页概述了$lookup管道阶段之前的替代过程。
MongoDB 应用程序使用以下两种方法之一来关联文档:
-
将一个文档的
_id
字段保存在另一文档中的Manual references作为参考。然后,您的应用程序可以运行第二个查询以返回相关数据。这些参考对于大多数用例而言都是简单且足够的。 -
DBRefs是使用第一个文档的
_id
字段的值,集合名称以及(可选)其数据库名称从一个文档到另一个文档的引用。通过包含这些名称,DBRef 可以使位于多个集合中的文档更容易与单个集合中的文档链接。
若要解析 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 具有以下字段:
-
$ref
$ref
字段保存引用文档所在的集合的名称。
-
$id
$id
字段包含所引用文档中_id
字段的值。
-
$db
- Optional.
包含引用文档所在的数据库的名称。
仅某些驱动程序支持$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。