Docs Menu

Docs HomeAtlas App Services

Relationships

On this page

  • Overview
  • Cardinality
  • To-One
  • To-Many
  • Embedded Object Relationships
  • Embedded Object to Another Collection
  • Embedded Object Within a List
  • Define a Relationship
  • 1. Define Schemas
  • 2. Create a New Relationship
  • 3. Configure the Relationship
  • 4. Deploy the Relationship

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 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 the customers collection has an accounts field that contains an array of every account_id value from the accounts 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 client queries. Without a relationship, the queries would return a list of just account_id values instead of the full Account objects.

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".

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:

data_sources/mongodb-atlas/example/pets/relationships.json
{
"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 SDK models:

{
"name": "Pet",
"properties": {
"name": "string",
"owner": "Person"
}
}
{
"name": "Person",
"properties": {
"name": "string"
}
}

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:

data_sources/mongodb-atlas/example/people/relationships.json
{
"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 SDK models:

{
"name": "Pet",
"properties": {
"name": "string"
}
}
{
"name": "Person",
"properties": {
"name": "string",
"pets": "Pet[]"
}
}

Embedded Objects can have relationships with foreign collections. Use dot notation to access properties in embedded objects.

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 }
}

An embedded object that is within a list property can have a relationship with a foreign collection.

{
"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.

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 field

  • The foreign key must be the _id field of the collection the field is referencing

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.

You define a relationship for collections in a linked MongoDB data source alongside the schema.

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.

←  Schema TypesValues & Secrets →