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.
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": "#/relationship/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.