Flatten nested fields (MongoDB)

Please be sure of your agent type and version and pick the right documentation accordingly.

This is the documentation of the forest-express-sequelize and forest-express-mongoose Node.js agents that will soon reach end-of-support.

forest-express-sequelize v9 and forest-express-mongoose v9 are replaced by @forestadmin/agent v1.

Please check your agent type and version and read on or switch to the right documentation.

Flatten nested fields (MongoDB)

This feature is available from forest-express-mongoose@8.1.0

Why flatten nested fields?

Forest Admin introspects your data structure recursively, so nested fields (object in object) are detected at any level deep.‌

By default, Forest Admin will use JSON widgets to show and edit this type of data.‌

In order to be able to display each field separately, you can flatten the sub-document.‌

Configuring the fields to flatten

Any flattening configuration will not affect your database structure, but only in-app data representation

In order to flatten a sub-document, you will first need to declare it in your code for a specific collection. Here we will flatten contactDetails. There are two ways of declaring the field to flatten‌

Here is the way to declare the fields to flatten.

You can only target root-level sub-documents

NameTypeDescription

fieldsToFlatten

string[] or {field, level}[]

  • it is possible to put the names directly - all the levels will be flattened

  • It is possible to specify the flattening level

    • field - name of the field

    • level - starts at 0

Let's imagine a collection...

module.exports = (mongoose, Mongoose) => {
  const schema = Mongoose.Schema({
    // root-level
    'id': Number,
    'name': String,
    'contactDetails':{
      //Level 1
      'phone': {
        //Level 2
        'homePhone': String,
        'mobilePhone': String,
      },
      'email': String,
    },
  }, {
    timestamps: false,
  });​

  return mongoose.model('users', schema, 'users');
};

...where we can flatten contactDetails as follows

forest/users.js
import { collection } from 'forest-express-mongoose';

collection('users', {
  actions: [],
  fields: [],
  segments: [],
  fieldsToFlatten: ['contactDetails'],
});

Reference management

Belongs to

If any field of a sub-document contains a reference, it will automatically be transformed into a belongsTo relationship.‌

Has many

If any of the fields in the sub-document is an array of references, it will automatically be transformed into a hasMany relationship and moved under Related data section.‌

Filter, search, and sort

As the flattened fields will be considered native fields, the searching, filtering, and sorting are automatically supported. You can disable it in the field's configuration.‌

Segments

You can build your segments using flattened fields as you would do with the native field. You can of course mix flattened and native fields in the segment definition.‌

Scopes

You can scope your data on flattened fields.‌

Editing flattened fields

You don't need to implement any specific logic for editing, Forest Admin will reconcile the data to the database format.‌

Every flattened field will appear in the application as an independent field, so you can configure the edit widget for it.‌

Routes

The flattener is intended to work automatically with the default routes (eg. the routes handled by default by Forest Admin which you have not overridden).

If you want to use the flatten feature with some custom routes, you will need to ensure that the data coming from outside of your server have been "reconciled", or in other word, that the flattener has translated the data sent from the web application into something corresponding to your database structure. To do so, you will need to activate the reconciliation mechanism on your own, by adding a simple middleware on top of your routes. Here is an example:

index.js
import { requestUnflattener } from 'forest-express-mongoose';

...

app.use('/forest', requestUnflattener);

By doing so, every routes related to forest will first, reconcile the data sent by the web application, and dispose them to you with a format corresponding to your database structure you can work with.

Last updated