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

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 resolved GraphQL types and SDK models:

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 resolved GraphQL types and SDK models:

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.

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.

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 →
Share Feedback
© 2023 MongoDB, Inc.

About

  • Careers
  • Investor Relations
  • Legal Notices
  • Privacy Notices
  • Security Information
  • Trust Center
© 2023 MongoDB, Inc.