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
});

recipeEntity.save();


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

complaintEntity.save();


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:

Recipe
.find()
.populate('Complaints')
.exec(callback);


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) {
        console.log(recipes);
    });
});

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

// add complaint for recipe
app.post('/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
        complaint.save(function (err) {
            if (err)
                return res.send(err);

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

})

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