Docs Menu
Docs Home
/ /
Atlas 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
  • Define Schemas
  • Create a New Relationship
  • Configure the Relationship
  • 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 on 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 an embedded object property contained in a list, use field1.[].field2 (for example, 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 (source) field cannot be _id.

  • The reference (source) field cannot be a required field.

  • If you are using Device Sync, the foreign key must be the _id field of the foreign collection.

1

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 Define & Enforce a Schema.

2

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

To create a new relationship:

  1. Click Schema in the left navigation menu.

  2. From the Collections tab, select the source collection.

  3. Toggle the View to JSON View, and click + Add Relationship.

To create a new relationship, add a relationship configuration object to the source collection's relationships.json file:

{
"<source field>": {
"ref": "#/relationship/<data source>/<db>/<collection>",
"foreign_key": "<foreign field>",
"is_list": <boolean>
}
}
3

A relationship definition maps from a reference field in the source collection's schema to a foreign field of the same type in the foreign collection's schema.

To configure the relationship:

  1. Specify the field in the source collection that the relationship maps from. This is referred to as the parent in the UI.

  2. Specify the foreign database, collection, and field in the foreign collection to map to the source field. These are referred to as linked in the UI. If you are using Device Sync, the linked field must be _id.

  3. Click Add.

To configure the relationship, specify the source field name as a root-level field in relationships.json, then add the following configuration options in the field's value:

  • Specify the foreign collection in the ref field using the following format:

    #/relationship/<data source>/<db>/<collection>
  • Specify the field to match in the foreign_key field. If you are using Device Synce, this must be _id.

  • If the source field contains an array, set is_list to true, otherwise set it to false.

4

Click Save, then deploy your updated application.

Save the relationship configuration file, and push your changes to deploy them:

appservices push

Back

Schema Data Types