Docs Home → Atlas App Services
Relationships
On this page
Overview
A relationship is a connection between two documents. Relationships allow you to reference and query related documents in read and write operations, even if the documents are in separate databases or collections.
You define a relationship for a "source" MongoDB collection and link to documents in a "foreign" collection. Atlas App Services automatically resolves relationships in synced SDK data models and GraphQL operations by replacing the values in a source field with the foreign documents that they reference.
Important
Relationships cannot span partitions
In an app that uses Partition-Based Sync, an object can only have a relationship with other objects in the same partition. The objects can exist in different databases and collections (within the same cluster) as long as the partition key value matches. To understand how partitions can span multiple databases and collections, see Partition-Based Sync.
Relationships are unidirectional and don't enforce uniqueness or other foreign key constraints. If you reference a non-existent foreign value in a source field, App Services automatically omits the reference from resolved relationships.
Example
Consider an application that has two collections:
The
accounts
collection contains documents that each describe a customer account.Account Collection Schema{ "title": "Account", "properties": { "_id": { "bsonType": "objectId" }, "account_id": { "bsonType": "string" }, "products": { "bsonType": "array", "items": { "bsonType": "string" } }, ... } } The
customers
collection contains documents that each describe a single customer that can have one or more accounts. Every document in thecustomers
collection has anaccounts
field that contains an array of everyaccount_id
value from theaccounts
collection that applies to the customer.Customer Collection Schema{ "title": "Customer", "properties": { "username": { "bsonType": "string" }, "accounts": { "bsonType": "array", "items": { "bsonType": "string" } }, ... } }
The app defines this relationship on the customers
collection. It
points from the array of account id values stored in the accounts
field to the account_id
field of each document in the
accounts
collection.
{ "accounts": { "ref": "#/realm/mongodb-atlas/sample_analytics/accounts", "foreign_key": "account_id", "is_list": true } }
With this relationship defined, App Services can return a customer and all
of their accounts in the same GraphQL query. Without a relationship,
the query would return a list of just account_id
values instead
of the full Account
objects.
query CustomerAccounts { customer(query: { username: "Elizabeth Ray" }) { username accounts { account_id products } } }
Cardinality
A relationship's cardinality determines the number of foreign documents that it can reference. App Services supports two relationship cardinalities: "to-one" and "to-many".
To-One
A to-one relationship links each source document with either a single document or an array of documents from the foreign collection.
To indicate that a relationship has "to-one" cardinality, set
is_list
to false
:
{ "owner": { "ref": "#/relationship/mongodb-atlas/example/people", "foreign_key": "_id", "is_list": false } }
App Services automatically replaces source values with the referenced objects or a null value in resolved GraphQL types and SDK models:
To-Many
A to-many relationship links each source document with a list of documents from the foreign collection.
To indicate that a relationship has "to-many" cardinality, set
is_list
to true
:
{ "pets": { "ref": "#/relationship/mongodb-atlas/example/pets", "foreign_key": "_id", "is_list": true } }
App Services automatically replaces source values with the referenced objects or a null value in resolved GraphQL types and SDK models:
Embedded Object Relationships
Embedded Objects can have relationships with foreign collections. Use dot notation to access properties in embedded objects.
Embedded Object to Another Collection
An embedded object can have a relationship with an object in a foreign collection.
{ "title": "Person", "properties": { "_id": { "bsonType": "objectId" }, "pet": { "bsonType":"object", "properties": { "favoriteToyBrand": { "bsonType": "objectId" } } } // ...additional model properties } }
Use dot notation to specify the embedded object property that has a relationship with the foreign collection. Then, you can specify the foreign collection details and foreign key field.
{ "pet.favoriteToyBrand": { "ref": "#/relationship/mongodb-atlas/example/ToyBrand", "foreign_key": "_id", "is_list": false } }
Embedded Object Within a List
An embedded object that is within a list property can have a relationship with a foreign collection.
Important
The GraphQL API does not currently support embedded object relationships.
You can resolve embedded object relationships with Atlas Device Sync and in the Realm SDKs.
{ "title": "Person", "properties": { "_id": { "bsonType": "objectId" }, "pets": { "bsonType":"array", "items": { "bsonType": "object", "properties": { "favoriteToyBrand": { "bsonType": "objectId" } } } } // ...additional model properties } }
To access a embedded object property contained in a list, use:
field1.[].field2
, e.g. pets.[].favoriteToyBrand
. From there,
you can specify the foreign collection details and foreign key field.
Tip
Use the same syntax with dictionaries and sets
You can use this same field1.[].field2
syntax when creating relationships
within dictionaries and sets.
{ "pets.[].favoriteToyBrand": { "ref": "#/relationship/mongodb-atlas/example/ToyBrand", "foreign_key": "_id", "is_list": false } }
Note
Primitives versus lists, dictionaries, and sets in relationships
In the example above, is_list
is set to false. The field at the end
of the relationship string here is a primitive, not a list. The embedded
object is contained in a list, but the favoriteToyBrand
property
itself is not a dictionary, set or list.
Define a Relationship
When you define a relationship, keep these limitations in mind:
The reference field must not be
_id
The reference field must not be a
required
fieldThe foreign key must be the
_id
field of the collection the field is referencing
1. Define Schemas
In order to define a relationship, you must have a schema defined for both the source collection and the foreign collection. To learn how to define schemas, see Enforce a Schema.
2. Create a New Relationship
You define a relationship for collections in a linked MongoDB data source alongside the schema.
3. Configure the Relationship
A relationship definition maps from a field included in the source collection's schema and points to a field of the same type in the foreign collection's schema.