对于MongoDB中的许多用例,将相关数据存储在单个文档中的非规范化数据模型将是最佳的。但是,在某些情况下,将相关信息存储在单独的文档中(通常存储在不同的集合或数据库中)是有意义的。
重要
MongoDB 3.2引入了$lookup
流水线阶段,以对同一数据库中的未分片集合执行左外部联接。有关更多信息和示例,请参见$lookup
。
从MongoDB 3.4开始,您还可以使用$graphLookup
管道阶段来加入未分片的集合以执行递归搜索。有关更多信息和示例,请参见
$graphLookup
。
该页面概述了$lookup
和$graphLookup
管道阶段之前的替代过程
。
MongoDB应用程序使用以下两种方法之一来关联文档:
手动参考,您可以将_id
一个文档的字段保存
在另一文档中作为参考。然后,您的应用程序可以运行第二个查询以返回相关数据。这些参考对于大多数用例而言都是简单且足够的。
DBRef是使用第一个文档的_id
字段,集合名称以及(可选)其数据库名称的值从一个文档到另一个文档的引用。通过包含这些名称,DBRef可以使位于多个集合中的文档更易于与单个集合中的文档链接。
若要解析DBRef,您的应用程序必须执行其他查询以返回引用的文档。许多驱动程序都有帮助程序方法,这些方法会自动形成DBRef的查询。驱动程序[1]不会自动将 DBRef解析为文档。
DBRef提供了一种通用的格式和类型来表示文档之间的关系。如果数据库必须与多个框架和工具进行交互,则DBRef格式还提供了表示文档之间链接的通用语义。
除非您有令人信服的理由使用DBRef,否则请改为使用手动引用。
[1] | 一些社区支持的驱动程序可能会有其他行为,并且可能会自动将DBRef解析为文档。 |
考虑以下操作,使用_id
第一个文档的字段作为第二个文档的参考来插入两个
文档:
然后,当查询从people
集合中返回文档时,您可以根据需要再次查询集合中places_id
字段所引用的文档places
。
DBRef具有以下字段:
$ref
该$ref
字段保存引用文档所在的集合的名称。
$id
该$id
字段包含_id
引用文档中该字段的值。
$db
可选的。
包含引用文档所在的数据库的名称。
仅某些驱动程序支持$db
参考。
例
DBRef文档类似于以下文档:
考虑来自在creator
字段中存储DBRef的集合中的文档
:
此示例中的DBRef指向数据库
creators
集合中位于其字段中的文档。users
ObjectId("5126bc054aed4daf9e2ab772")
_id
注意
DBRef中字段的顺序很重要,使用DBRef时必须使用上述顺序。
司机 | DBRef支持 | 笔记 |
---|---|---|
C | 不支持 | 您可以手动遍历引用。 |
C ++ | 不支持 | 您可以手动遍历引用。 |
C# | 支持的 | 请参阅C#驱动程序页面 以获取更多信息。 |
哈斯克尔 | 不支持 | 您可以手动遍历引用。 |
爪哇 | 支持的 | 请参阅Java驱动程序页面 以获取更多信息。 |
Node.js | 支持的 | 请参阅Node.js驱动程序页面 以获取更多信息。 |
佩尔 | 支持的 | 请参阅Perl驱动程序页面 以获取更多信息。 |
的PHP | 不支持 | 您可以手动遍历引用。 |
python | 支持的 | 请参阅PyMongo驱动程序页面 以获取更多信息。 |
Ruby | 支持的 | 请参阅Ruby驱动程序页面 以获取更多信息。 |
斯卡拉 | 不支持 | 您可以手动遍历引用。 |