Eduardo Spaki Eduardo Spaki - 3 years ago 77
Node.js Question

two way navigation in a mongo one to n relashionship

I'm having hard times with the mongoose relashionship system.
Here are my schemes:

const mongoose = require('mongoose');

const RecipeSchema = mongoose.Schema({
Title: { type: String },
Description: { type: String },
Complaints: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Complaint' }]

const Recipe = mongoose.model('Recipe', RecipeSchema);

const ComplaintSchema = mongoose.Schema({
Recipe : { type: mongoose.Schema.Types.ObjectId, ref: 'Recipe' },
Message: { type: String }

const Complaint = mongoose.model('Complaint', ComplaintSchema);

And here are how I'm saving my data:

var recipeEntity = new Recipe({
Title: request.body.Title,
Description: request.body.Description

var complaintEntity= new Complaint({
Message: request.body.Message.trim(),
Recipe: mongoose.Types.ObjectId(request.body.Message.RecipeId);

So far, so good... at least to me!

And now, when I try to list the recipes with the complaints, I just got an empty array of complaints:


And here is the json result:

"Id": "595fe6f89d63700011ee144d",
"Title": "Chocolate Cake",
"Description": "aaaa bbb cc d"
"Complaints": []

So, what am I missing here?
tks for your support

Answer Source

I am going to assume that you are not saving both recipe and complaint during the same call. That would not make any sense: everytime you make a complaint, you wouldn't make a recipe too.

When you create a complaint, you need to save its associated recipe's ObjectId AND also add/push the complaint's ObjectId into the associated recipe's complaints.

If you are following resource naming conventions, you would have something like:

// get recipes including complaints
app.get('/recipes', function (req, res) {
    Recipe.find().populate('Complaints').exec(function (err, recipes) {

// add recipe'/recipes', function (req, res) {
    var recipe = new Recipe(req.body); // simplified (err) {
        if (err)
            return res.send(err);    

// add complaint for recipe'/recipes/:recipeID/complaints', function (req, res) {

    // we query recipe bc we need it after
    Recipe.findById(req.params.recipeID, function (err, recipe) {
        if (err)
            return res.send(err);
        if (!recipe)
            return res.send('No recipe found');

        // add complaint
        var complaint = new Complaint(req.body);
        complaint.Recipe = recipe._id; // add reference in one direction (err) {
            if (err)
                return res.send(err);

            // update recipe
            recipe.Complaints.push(complaint._id); // add reference in other direction
   (err) {
                if (err)
                    return res.send(err);    


I think this is a good read: many to many relationship with nosql (mongodb and mongoose).

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download