DEV Community

Getting started with Mongoose discriminators in Express.js

Nienke on February 12, 2018

I recently started rewriting my Rails side project, what.pm, to Express. One reason is that I want to get better at JavaScript, the other is that R...
Collapse
 
the_hme profile image
Brenda 🐱 • • Edited

Update below:

Thanks for starting this post. I am using Mongoose 5.3 and I'm having issues with making changes to my existing schema.

I don't have each model in different files, they are all in the same file and then get exported as part of a single app schema, so how would I access Base within the same file. I tried something like this:

const Base = new mongoose.Schema({
      title: { type: String, required: true },
      date_added: { type: Date, required: true },
      redo: { type: Boolean, required: false },
    }, baseOptions,
  );

const BookSchema = new mongoose.Schema({
    author: { type: String, required: true },
  });

var Book = Base.discriminator('Book', BookSchema);
...
this.Base = mongoose.model('Base', Base);
this.Book = mongoose.model('Book', Book);
Enter fullscreen mode Exit fullscreen mode

However, when I try to load my app, it complains with error:

Base.discriminator is not a function

I tried upgrading mongoose to version 5.4.2 and I am still getting this error.

UPDATE: My issue seems related to the fact that I need to work on a deeply embedded doc and this array of objects is what needs to be able to inherit from the base class. Example, person object with embedded belongings array, which contains a media array, where the movies, books, etc. are store and these media items need to share a schema

Collapse
 
rifaldikn profile image
Rifaldikn •

Same with me, did u solve it?

Collapse
 
mrtarikozturk profile image
mrtarikozturk •

Hi, Thank you so much for your post. I have a question. I did my models like above. However, I don't have different colletions for my models in database. Is it normal? Additionally, I want to different collection for my models. How can I do it? Could you share any source or give information?

Collapse
 
zahraa_mazloum_fa93a5e748 profile image
Zahraa Mazloum •

Hello , did you solve it please?

Collapse
 
hisham profile image
Hisham Mubarak •

Thanks a lot for using the perfect example to demonstrate the use cases and output. Many other articles and even the original documentation used some complex event logging example which a beginner like me couldn't make any sense of.

Collapse
 
tichel profile image
tichel •

Nienke, great article that helped me a lot! What would be the routes from app.js to this Schemes.. ? Routes via models/book.js, models/tvshow.js or via the models.base.js? Many thanks, Peter Tichelaar

Collapse
 
helenasometimes profile image
Nienke •

Hi Peter,

I set up my routes in app.js like this:

const routes = require('./routes/routes');
// bunch of middleware
app.use('/', routes);

And then in routes.js, I call my controllers:

const base_controller = require('../controllers/baseController');
const creation_controller = require('../controllers/creationController');

and inside baseController, I call my models like this:

const Book = require('../models/book');
const Movie = require('../models/movie');
const Tvshow = require('../models/tvshow');
const Base = require('../models/base');

If I want to, for example, get an item by its ID, I do this inside my controller:

// Get item by ID
exports.get_item_by_id = function(req, res, next) {
    async.parallel({
        function(callback) {
            Base.findById(req.params.id)
                .exec(callback);
        },
    }, function(err, results) {
        if (err) { return next(err); }
        res.render('templates/update', { data: results });
    });
};

Then in my routes, I do this:

router.get('/update/:id', ensureAuthenticated, base_controller.get_item_by_id, (req, res) => {
    res.send(req.params);
});

Hope that helps any? I'm planning on open sourcing my code at some point, it just needs a lot of cleaning up :/

Collapse
 
joanlamrack profile image
Joan Lamrack •

Nice article!, been looking for throughout explanation about this

Collapse
 
sahilkashyap64 profile image
Sahil kashyap •

Thanks for sharing this. It was easy to understand. I applied it in my "user role access" system and it worked.

Collapse
 
javabytes profile image
JavaBytes •

Very clear step by step article! Found this super useful!

Collapse
 
burakkarakus profile image
Burak Karakus •

This is a really helpful post which quickly and greatly show how to use mongoose discriminators! Thank you!

Collapse
 
adityagaddhyan profile image
Aditya Gaddhyan •

Thanks man! I really liked your blog.

Collapse
 
estebangs profile image
Esteban •

...but, how do you actually create a new derived schema???

Collapse
 
ilhamtubagus profile image
Fian •

thanks for your post. I have a question. I wonder, how i could select all of documents in my collection will all discriminators included ?

Collapse
 
tharindurewatha profile image
Tharindu Rewatha •

Thank you so much for the post. This was the only post on the internet that described mongoose discriminator function clearly.

Collapse
 
uahmadsoft profile image
UAhmadSoft •

GREAT Post indeed ..........
but Plz explain me what is purpose of BaseOptions ???

Collapse
 
byrneg7 profile image
byrneg7 •

Brilliant article Nienke, great choice of use-case to illustrate an OO approach to Express+ Mongoose