How do you create a one to many relationship using mongo db realm?

I have 2 documents one called clients one called jobs. I want to link every job to a client and a client to multiple jobs. I have managed to add a relationship from the job to the client using the client id. How can i link the client to every job using its ID?

This is my clients document schema:

    {
      "title": "client",
      "properties": {
        "__v": {
          "bsonType": "int"
        },
        "_id": {
          "bsonType": "objectId"
        },
        "name": {
          "bsonType": "string"
        },
        "surname": {
          "bsonType": "string"
        },
        "jobs": {
          "bsonType": "array"
        }
      }
    }

and this is my jobs document schema:

    {
      "title": "job",
      "properties": {
        "_id": {
          "bsonType": "objectId"
        },
        "client_id": {
          "bsonType": "objectId"
        }
     }

}

I want to have a jobs array under client that links to all the jobs with the client_id of that client

2 Likes

Hi Paula,

Thanks for making your first post and welcome to the community!

It sounds like you want to create an inverse relationship.

Please see the documentation below for how to do this, the examples are in iOS SDK but you can find a similar documentation for the SDK you’re working with.

Following the example in the link above, your client_id property would look something like this:
let client_id = LinkingObjects(fromType: Client.self, property: "jobs")

Regards
Manny

1 Like

Hi Manny,

Thanks!
Thankyou for the link however i came across that documentation before and wasn’t sure how to apply it to my use case. To create schemas and relationships i’m using the relationships tab from the realm gui you can see below:

so where would i apply that link?
Currently my client_id relationship looks like this:
“client_id”: {
“ref”: “#/relationship/mongodb-atlas/jonara-business-system/clients”,
“foreign_key”: “_id”,
“is_list”: false
},

Hi Paula,

The relationship link you provided is not a list so it would just be a one to one relationship.

Based on the requirement you provided I would create a one to many relationship on the Client.jobs property where the relationship link would look something like this:

“jobs”: {
“ref”: “#/relationship/mongodb-atlas/jonara-business-system/job”,
“foreign_key”: “_id”,
“is_list”: true
},

This would allow you to have an array of job objects in this property under the Client collection.
The equivalent code in your Client class for this relationship would be:

let jobs = List<Job>()

Note: if you have development mode on in your Realm app, it will automatically create the relationship in the UI (preventing the need to create it manually as per your screenshot). Additive changes from your client code will apply to your schema automatically when sync happens.

The inverse part is added on top of the one-to-many relationship above and is defined only in the code. The inverse relationship does not get created in the UI nor is it included in the schema i.e. client_id would not be in your schema.

let client_id = LinkingObjects(fromType: Client.self, property: "jobs")

This allows the value for the Job.client_id to automatically update with the Client object that it is related to. Keep in mind the inverse relationship in Realm is local to the database and does not get pushed to cloud.

Regards

Hi Mansoor,
Thanks for your reply.
Yes i understand that the relationship link i provided would be a one to one relationship because that relationship is being used to link a job to a client from the jobs side. Is this wrong?

I also tried to add the one to may relationship like you did, however, i get this error:
“error validating rule relationships: items must only have a single schema for “jobs””.

My clients schema is in my first comment in this post and the jobs object is the following:
“jobs”: {
“bsonType”: “array”
}

How can this be avoided? As i had already tried this before posting my question.

And where would this piece of code be added? let jobs = List(). Taking into consideration that im using the Realm UI to manage my schemas.

Thanks a lot for your help.

Are you attempting to create relationships only within the Realm Console? Are you also only using the console to work with your schema’s? Is this a web app only? Java?

If you can answer the above, we may be able to provide more concrete examples and help.

This is also a cross post to SO so here’s the link

How do you create a one to many relationship using mongodb realm web ui?

in case an answer pops up there.

Hi Jay,

Are you attempting to create relationships only within the Realm Console? - Yes

Are you also only using the console to work with your schema’s? - Yes, however if there is an easier way to do this i am willing to learn. I am only using the Realm UI because i am new to databases and backend development and this was the only way i could understand.

Is this a web app only? Java? - It is a react application

Hi Mansoor,

I managed to update my schema to get the relationship you mentioned above, working. However i am coming across one tiny issue. With these relationships, when querying the document using GraphQL, it is returning all the list of jobs and not just the jobs for that particular client. Is there a relationship in atlas that handles this type of filter? or does this need to be done through graphql?

Clients schema:

 "_id": {
  "bsonType": "objectId",
 }
"jobs": {
      "bsonType": "array",
      "items": [
        {
          "bsonType": "objectId"
        }
      ],
      "unique": true
    }

Relationship in clients collection:

{
 "jobs": {
"ref": "#/relationship/mongodb-atlas/jonara-business-system/jobs",
"foreign_key": "_id",
"is_list": true
},

Jobs schema:

"_id": {
  "bsonType": "objectId"
},
"client_id": {
  "bsonType": "objectId"
}

Relationship in jobs collection:

   "client_id": {
"ref": "#/relationship/mongodb-atlas/jonara-business-system/clients",
"foreign_key": "_id",
"is_list": false
}

GraphQL query:

query get_clients {
  clients {
    _id
    name
    jobs {
      _id
    }
  }
}
1 Like

Hi, Do you think you could look at my latest update please? How do you create a one to many relationship using mongo db realm? - #8 by Paula_farrugia

I am very close to getting the relationship to work but need some clarification whether I am doing something wrong when linking the relationships or if the filtering needs to be done through graphql.

Appreciate your help.

Thanks,
Paula

1 Like

I’m running into the same problem with a very similar schema. Did you ever find a solutino @Paula_farrugia ?

2 Likes

I’m also having the same issue here.

I’m noticing that SDK docs include documentation for inverse relationships (the React Native SDK docs, for example) while doc for relationships doesn’t have anything for inverse relationships. Are inverse relationships unavailable through GraphQL?

Unfortunately not Michael, i did not get any updates or help from anyone at Mongodb so did not end up solving the above issue. Would be good if we get an update to get this working.

@Paula_farrugia, what did you wind up doing if you don’t mind my asking?

I ended up scratching it entirely as the fix i found was taking too long to render every time but basically i created a custom graphql resolver and function that maps the data i wanted and maps the totals manually. In the function i used lookup to match them:

 clientRecords.aggregate([
      {
          $lookup: {
              from: "jobs",
              localField: "_id",
              foreignField: "client_id",
              as: "totalJobs"
          }
      },
  ]).toArray();

It works but too slow for large amounts of data.