I'm designing out a mongodb schema that will be used to generate a dynamic user interface used to collect data. The basic idea is to have a "Template" document contain a definition of all the fields in the user interface. Within that same "Template" document, there is a schema that defines the layout of the interface. The interface has a nested structure of sections, subsections, field groups, and fields; this hierarchy corresponds to logical groupings of related data. To manage user access, we also need to define "Views" within the "Template" document as well. A "View" defines what sections, subsections, field groups, and fields can be visible. We would only need to retrieve one View at a time so we want to filter, and project the portions of the "Template" visible for a specific view. So far this is our schema:
{
_id: ""
"TemplateName": "Template 1"
"sections": [{
"name": "Details",
"sort": "1",
"views": ["View1"],
"subSections": [{
"name": "General",
"sort": "1",
"views": ["View1"],
"fieldGroups": [{
"name": "Group 1",
"sort": "1",
"fields": [{
"fieldId": "59d662a6c153f67518f98880",
"sort": "1",
"views":[{
"name":"View1",
"access":"read"
}]
},
{
"fieldId": "59d662a6c153f67518f98881",
"sort": "1",
"views":[{
"name":"View1",
"access":"read"
}]
}]
}]
}]
}]
}
Now this design works great since we limit the amount of duplication by embedding the names of views in a particular sub document that is included in that view. For example the "Details" section is visible in "View 1". The problem is how to query this document efficiently based on view name and project only the specific sections, subsections, fieldGroups, and fields that have the view name inside of their views array property. I've only been able to do this by first unwinding, then using the match operator, but this is messy since we have to unwind at progressively deeper levels to get the full structure.
Advice and recommendations are appreciated here.