Feature(s) impacted
Many-to-Many relation using MongoDB
Observed behavior
collection.addManyToManyRelation() method requires a throughCollection parameter.
Expected behavior
In MongoDB, I should be able to create many-to-many relationship without the junction table.
Context
- Database type: MongoDB
- NodeJS 18.17.1
- Library from package-lock - “@forestadmin/forest-cloud”: “1.12.39”
I’m trying to set up a many-to-many relationship in Forest Admin Cloud Agent with MongoDB where I have Projects that contain an array of Cause IDs (causeIds).
I want to display this array of “cause names” corresponding to cause IDs in the UI.
The TypeScript definition for addManyToManyRelation() requires a throughCollection parameter, but there is no physical through collection in my MongoDB setup since the relationship is handled via an array in the document.
My current code looks like this:
agent.customizeCollection('projects', collection => {
collection.addManyToManyRelation(
'causes',
'causes',
// What should I put here for the throughCollection parameter?
{
originKey: 'causeIds' // Field in projects containing the array of cause IDs
}
);
});
What’s the recommended approach for MongoDB array-based relationships in the Forest Admin Cloud Agent?
I have also tried setting Dynamic Dropdown and Dynamic Checkbox in the Projects collection. (Refer to the screenshot)
The issue with this approach is - when a user selects a particular cause from the options (while editing or creating the record), the name of the cause is stored in the database. I want name just for the display and user experience purposes while ID should be stored in the database.
Hello @Pankaj_P,
In the scenario that you described, a “virtual” through table should have already been generated by Forest Admin in order to emulate the relationship. You should not need to declare an additionnal relationship using addManyToManyRelation
.
You collections list should contain a projects_causes
that already represents it.
Thanks for your suggestion, Nicolas.
I searched the collection list on the dashboard, and I also checked in .forestadmin-schema.json file for any instance of a table with attribute “isVirtual”: true, but I could not find any virtual table. Is it possible that Forest Admin has missed reading this relation? If yes, can I create a virtual table on my own through code?
Can you please let me know the project and environment concerned, so that I can look into the schema that was sent to forest admin 
Organization name: Project-V-Org
Project: Project-V-Admin-Panel
Environment: Production
Forest Admin ‣ Data ‣ Causes
Thank you @Pankaj_P for your input.
Having looked into your schema, it seems like indeed, we do not detect a relationship between Projects and Causes. The causes
is detected as a list of string, and not a list of ObjectIds.
However, I did find relationships between projects and other document types. Did you setup your mongodb schema differently for those ? Maybe this could explain why the relationship Project ↔ Causes is not detected.
addManyToManyRelation
will not really work for your use case since you are lacking an actual through table. It is more targetted to SQL datasources, where some relationships are not explicit in the schema.
Would you be able to provide a way to reproduce the issue on our side ? For instance to provide us (in MP for instance) with a public mongodb URI containing a sample of Project documents with causes, that we can use to test and resolve the issue ?
Thanks !
In projects, we have causes and skills where the list of ids are stored in an array. In both the cases, relationship is not detected.
The other instance is of a project owner, which is a many-to-one relation, and it is detected correctly. But it’s not right to compare causes or skills (M2M) with project owners (M2O).
In the entire project, I can not see any many-to-many relation detected.
I’ll share public mongodb URI containing a sample of Project documents with causes in some time
@Nicolas.M Can you share you email address?
I have shared my email address in a private message on this forum 
I have emailed you with the details
Thanks,
Looking into it !
I have tried with the public database that you provided, but unfortunately did not manage to reproduce the case that you have.
In the case provided, I have a through table Project_Causes that is automatically generated.
I think I have found the root cause of your issue though: the “causes” do not have an ObjectId key but a string key. And I believe that some of your string ids might not be up to date.
The way the mongodb datasource works is that we sample some documents to detect potential relationships, and build them if the complete sample keys are correctly pointing to other documents in the database.
In your case, it must have detected that some string ids do not point to any existing document, and therefore assumes that there is no actual relationship
I see a couple ways to work around the issue:
→ you can try and fix the incorrect ids that you have in your database. The best would be to convert your cause ids to be actual objectIds, and not strings, but I understand this may not be an option since it will alter your data schema.
→ you can try to create virtual relationships as highlighted in this documentation : Computed foreign keys | Node.js Developer Guide
I hope this helps
The data does have some IDs in the Project table’s causes field that do not have a corresponding record in the Cause table. I shall check out the options you have suggested.
Can you confirm that with this junction table in place, I can reference cause-name instead of cause ID in Project table’s causes column?
Hello @Pankaj_P,
Unfortunately, the creation of the through table will remove the causes column from the Projects table, since it now seen as a one to many from the Projects’ collection perspective. The causes will be displayed in the Related Data section of the interface.
You may have to explore the virtual relationships options to setup your Projects collection this way.