mongo one到n relashionship中的双向导航

时间:2017-07-09 14:34:40

标签: node.js mongodb mongoose relational-database

我对猫鼬关系系统感到困难。 以下是我的计划:

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

以下是我保存数据的方法:

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

到目前为止,非常好......至少对我而言!

现在,当我尝试列出有关投诉的食谱时,我得到的是一系列投诉:

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

这是json的结果:

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

那么,我在这里错过了什么? 请求支持

2 个答案:

答案 0 :(得分:1)

我将假设您在同一个电话中没有保存食谱和投诉。这没有任何意义:每次你投诉时,你都不会制作食谱。

当您创建投诉时,您需要保存其关联的食谱ObjectId ,同时将投诉的ObjectId添加/推送到相关食谱的投诉中。

如果你关注resource naming conventions,你会有类似的事情:

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

})

我认为这是一本很好的读物:many to many relationship with nosql (mongodb and mongoose)

答案 1 :(得分:1)

好的,我是如何在参考文件中保存记录的,我采用了这种方法:

RecipeSchema.pre('remove', function(next) { 
    Complaint.remove({ "Recipe" : this._id }).exec();
    next();
});

ComplaintSchema.pre('remove', function(next) {
    Recipe.findById(this.Recipe).exec((error, item) => {
      var index = item.Complaints.indexOf(item.Complaints.find(e => e._id == this._id));
      item.Complaints.splice(index, 1);
      item.save(() => { next(); });
    });
});

ComplaintSchema.pre('save', function(next) {
    Recipe.findById(this.Recipe).exec((error, item) => {
      item.Complaints.push(this);
      item.save(() => { next(); });
    });
});

使用mongo架构上提供的此触发器/事件。 这非常有效!