关系
Overview
关系是两个文档之间的联系。您可以通过关系在读写操作中引用和查询相关的文档,即使这些文档位于单独的数据库或集合中。
您可以在源 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。 此处关系string末尾的字段是基元,而不是列表。 嵌入式对象包含在列表中,但favoriteToyBrand
属性本身不是字典、集或列表。
定义关系
在定义关系时,请记住以下限制:
引用(源)字段不能为
_id
。引用(源)字段不能是
required
字段。如果您使用 Device Sync,则外键必须是外部集合的
_id
字段。
定义模式
要定义关系,必须为源集合和外部集合定义模式。 要了解如何定义模式,请参阅定义和实施模式。
创建新关系
您可以在关联的 MongoDB 数据源和模式中定义集合的关系。
创建新关系:
单击左侧导航菜单中的 Schema(应用用户)。
从Collections标签页中,选择源集合。
将View切换到 JSON 视图,然后单击+ Add Relationship 。
要创建新关系,请将关系配置对象添加到源集合的relationships.json
文件:
{ "<source field>": { "ref": "#/relationship/<data source>/<db>/<collection>", "foreign_key": "<foreign field>", "is_list": <boolean> } }
配置关系
关系定义将源集合模式中的引用字段映射到外部集合模式中相同类型的外部字段。
要配置关系,请执行以下操作:
指定关系映射的源集合中的字段。 这在用户界面中称为父项。
指定外部数据库、集合以及外部集合中要映射到源字段的字段。 这些在用户界面中称为“已链接”。 如果您使用的是 Device Sync,则链接字段必须为
_id
。单击 Add(连接)。
要配置关系,请在relationships.json
中将源字段名称指定为根级字段,然后在字段值中添加以下配置选项:
使用以下格式在
ref
字段中指定外部集合:#/relationship/<data source>/<db>/<collection> 在
foreign_key
字段中指定要匹配的字段。 如果您使用的是 Device Sync,则必须为_id
。如果源字段包含大量,则将
is_list
设立为true
,否则设立其设置为false
。