数据库参考
在MongoDB的许多用例中,将相关数据存储在单个文档中的非规范化数据模型是最优的。然而,在某些情况下,将相关信息存储在不同的文档中,通常是不同的集合或数据库中,是有意义的。
重要
您可以使用$lookup
管道阶段来执行与同一数据库中未分片的集合的左外连接。
您还可以使用$graphLookup
管道阶段来将未分片的集合连接起来执行递归搜索。
本页概述了在$lookup
和$graphLookup
管道阶段之前的替代程序。
您可以为以下环境中的部署创建数据库引用
MongoDB Atlas:云中MongoDB部署的全托管服务
MongoDB Enterprise:基于订阅的自托管MongoDB版本
MongoDB Community:源代码可用的、免费使用且可自托管的MongoDB版本
MongoDB应用程序使用两种方法之一来关联文档
手动参考将一个文档的
_id
字段保存到另一个文档中作为引用。您的应用程序运行第二个查询以返回相关数据。这些引用对于大多数用例来说是简单且足够的。DBRefs是使用第一个文档的
_id
字段、集合名称、可选的数据库名称以及任何其他字段从一个文档到另一个文档的引用。DBRefs允许您更容易地引用存储在多个集合或数据库中的文档。
为了解析DBRefs,您的应用程序必须执行额外的查询以返回引用的文档。一些MongoDB驱动程序提供辅助方法以启用DBRefs解析为文档,但这并不是自动发生的。
DBRefs提供了一个通用的格式和类型,用于表示文档之间的关系。DBRef格式还提供了在数据库需要与多个框架和工具交互时表示文档之间链接的常用语义。
除非您有使用DBRefs的充分理由,否则请使用手动引用。
手动引用
背景
手动引用是指在另一个文档中包含一个文档的_id
字段。然后,应用程序可以发出第二个查询以按需解析引用字段。
在MongoDB Atlas UI中创建手动引用
要在MongoDB Atlas UI中创建手动引用,请按照以下步骤操作
在MongoDB Atlas UI中,转到为您的项目创建的集群页面。
如果尚未显示,请从导航栏中的 组织菜单选择包含您的项目组织。。
如果尚未显示,请从导航栏中的项目菜单选择您的项目。
如果尚未显示,请点击侧边栏中的集群。
集群页面将显示。
在 人员
集合中添加一个文档,该文档引用了 地点
中的条目。
在左侧导航面板中选择不同的集合。本例引用了一个
人员
集合。点击插入文档。
点击JSON视图图标({{}})。
将以下数据粘贴到文档中
{ "_id": { "$oid": "651aebeb70299b120736f443" }, "name": "Erin", "places_id": "651aea5870299b120736f442" "url": "bc.example.net/Erin" } 点击 插入。
当查询返回来自
人员
集合的文档时,如果需要,您可以对来自地点
集合的文档进行查询结果过滤,以获取由places_id
字段引用的文档。要了解更多关于在 MongoDB Atlas 中运行查询的信息,请参阅 MongoDB Atlas 文档中的查看、过滤和排序文档。
在终端中创建手动引用
考虑以下操作来插入两个文档,使用第一个文档的 _id
字段作为第二个文档的引用。
original_id = ObjectId() db.places.insertOne({ "_id": original_id, "name": "Broadway Center", "url": "bc.example.net" }) db.people.insertOne({ "name": "Erin", "places_id": original_id, "url": "bc.example.net/Erin" })
然后,当查询返回来自 人员
集合的文档时,如果需要,可以对 地点
集合中 places_id
字段引用的文档进行第二次查询。
使用
在几乎所有需要存储两个文档之间关系的场景中,请使用手动引用。手动引用创建简单,您的应用程序可以根据需要解析引用。
手动链接的唯一限制是这些引用不传达数据库和集合名称。如果您有一个集合中的文档与多个集合中的文档相关联,您可能需要考虑使用DBRefs。
DBRefs
背景
DBRefs是一种表示文档的约定,而不是特定的引用类型。除了来自_id
字段的值外,还包括集合名称,在某些情况下还包括数据库名称。
可选的,DBRefs可以包含任意数量的其他字段。额外的字段名称必须遵循服务器版本强加的任何字段名称规则。
格式
DBRefs 有以下字段
$ref
$ref
字段包含引用文档所在集合的名称。
$id
$id
字段包含引用文档中_id
字段的值。
$db
可选。
包含引用文档所在数据库的名称。
示例
DBRef 文档类似于以下文档
{ "$ref" : <value>, "$id" : <value>, "$db" : <value> }
考虑一个存储在 creator
字段中的 DBRef 的集合文档
{ "_id" : ObjectId("5126bbf64aed4daf9e2ab771"), // .. application fields "creator" : { "$ref" : "creators", "$id" : ObjectId("5126bc054aed4daf9e2ab772"), "$db" : "users", "extraField" : "anything" } }
此示例中的 DBRef 指向 users
数据库中 creators
集合的文档,该文档在 _id
字段中具有 ObjectId("5126bc054aed4daf9e2ab772")
。它还包含一个可选字段。
注意
DBRef 中字段的顺序很重要,在使用 DBRef 时必须使用上述顺序。
DBRefs 的驱动程序支持
驱动程序 | DBRef 支持 | 备注 |
---|---|---|
C | 不支持 | 您可以手动遍历引用。 |
C++ | 不支持 | 您可以手动遍历引用。 |
C# | 支持 | 请参阅 C# 驱动程序页面 获取更多信息。 |
Go | 不支持 | 您可以手动遍历引用。 |
Haskell | 不支持 | 您可以手动遍历引用。 |
Java | 支持 | 请参阅 Java 驱动程序页面 获取更多信息。 |
Node.js | 支持 | 请参阅 Node.js 驱动程序页面 获取更多信息。 |
Perl | 支持 | 请参阅 Perl 驱动程序页面 获取更多信息。 |
PHP | 不支持 | 您可以手动遍历引用。 |
Python | 支持 | 请参阅 PyMongo 驱动程序页面 获取更多信息。 |
Ruby | 支持 | 请参阅Ruby驱动页面获取更多信息。 |
Scala | 不支持 | 您可以手动遍历引用。 |
使用
在大多数情况下,您应该使用手动引用方法连接两个或更多相关文档。然而,如果您需要从多个集合中引用文档,请考虑使用DBRefs。