关系
概述
关系是两个文档之间的联系。您可以通过关系在读写操作中引用和查询相关的文档,即使这些文档位于单独的数据库或集合中。
您可以为“源”MongoDB 集合定义一个关系,并链接到“外部”集合中的文档。 Atlas App Services 通过将源字段中的值替换为它们引用的外部文档,自动解析同步的 SDK 数据模型中的关系。
关系是单向的,不会实施唯一性或其他外键约束。如果您在源字段中引用不存在的外部值,App Services 自动在解析的关系中忽略该引用。
例子
请考虑一个具有两个集合的应用程序:
accounts
集合包含每个描述客户帐户的文档。帐户集合模式{ "title": "Account", "properties": { "_id": { "bsonType": "objectId" }, "account_id": { "bsonType": "string" }, "products": { "bsonType": "array", "items": { "bsonType": "string" } }, ... } } customers
集合包含一些文档,它们均描述一个可以具有一个或多个帐户的客户。customers
集合中的每个文档具有一个accounts
字段,其中包含accounts
集合中适用于客户的每个account_id
值的数组。客户集合模式{ "title": "Customer", "properties": { "username": { "bsonType": "string" }, "accounts": { "bsonType": "array", "items": { "bsonType": "string" } }, ... } }
应用在 customers
集合上定义该关系。它从 accounts
字段中存储的帐户 ID 值数组指向 accounts
集合中的每个文档的 account_id
字段。
{ "accounts": { "ref": "#/relationship/mongodb-atlas/sample_analytics/accounts", "foreign_key": "account_id", "is_list": true } }
定义此关系后,App Services 可以在客户端查询中返回客户及其所有帐户。如果没有关系,查询将返回仅包含account_id
值的列表,而不是完整的Account
对象。
关联基数
关系的关联基数决定了它可以引用的外部文档数。App Services 支持两种关系关联基数:“一对一”和“一对多”。
一对一
一对一关系将每个源文档与外部集合中的单个文档或文档数组相关联。
要指示关系具有“一对一”关联基数,请将 is_list
设置为 false
:
{ "owner": { "ref": "#/relationship/mongodb-atlas/example/people", "foreign_key": "_id", "is_list": false } }
App Services 会自动将源值替换为 SDK 模型中引用的对象或 null 值:
{ "name": "Pet", "properties": { "name": "string", "owner": "Person" } } { "name": "Person", "properties": { "name": "string" } }
一对多
一对多关系将每个源文档与外部集合中的一组文档相关联。
要指示关系具有“一对多”关联基数,请将 is_list
设置为 true
:
{ "pets": { "ref": "#/relationship/mongodb-atlas/example/pets", "foreign_key": "_id", "is_list": true } }
App Services 会自动将源值替换为 SDK 模型中引用的对象或 null 值:
{ "name": "Pet", "properties": { "name": "string" } } { "name": "Person", "properties": { "name": "string", "pets": "Pet[]" } }
嵌入式对象关系
嵌入式对象可以与外部集合建立关系。使用点符号访问嵌入式对象中的属性。
嵌入式对象与另一个集合
嵌入式对象可以与外部集合中的对象之间具有关系。
{ "title": "Person", "properties": { "_id": { "bsonType": "objectId" }, "pet": { "bsonType":"object", "properties": { "favoriteToyBrand": { "bsonType": "objectId" } } } // ...additional model properties } }
使用点符号指定与外部集合之间具有关系的嵌入式对象属性。然后,您可以指定外部集合详细信息和外键字段。
{ "pet.favoriteToyBrand": { "ref": "#/relationship/mongodb-atlas/example/ToyBrand", "foreign_key": "_id", "is_list": false } }
列表中的嵌入式对象
列表属性中的嵌入式对象可以与外部集合之间具有关系。
{ "title": "Person", "properties": { "_id": { "bsonType": "objectId" }, "pets": { "bsonType":"array", "items": { "bsonType": "object", "properties": { "favoriteToyBrand": { "bsonType": "objectId" } } } } // ...additional model properties } }
要访问列表中包含的嵌入式对象属性,请使用 field1.[].field2
,例如 pets.[].favoriteToyBrand
。从此处,您可以指定外部集合详细信息和外键字段。
提示
对字典和集合使用相同的语法
在字典和集合中创建关系时,您可以使用这种相同的 field1.[].field2
语法。
{ "pets.[].favoriteToyBrand": { "ref": "#/relationship/mongodb-atlas/example/ToyBrand", "foreign_key": "_id", "is_list": false } }
注意
关系中的基元与列表、字典和集合
在上面的示例中,is_list
设置为 false。此处的关系字符串末尾的字段是基元,而不是列表。嵌入式对象包含 在列表中,但 favoriteToyBrand
属性本身不是字典、集合或列表。
定义关系
在定义关系时,请记住以下限制:
引用字段不能是
_id
引用字段不能是
required
字段外键必须是字段引用的集合的
_id
字段
1. 定义模式
要定义关系,您必须为源集合和外部集合定义模式。要了解如何定义模式,请参阅实施模式。
2.创建新的关系
您可以在关联的 MongoDB 数据源和模式中定义集合的关系。
3. 配置关系
关系定义映射源集合模式中包括的字段,并指向外来集合中模式中相同类型的字段。