如何更新mongodb嵌套数组中的值?

时间:2017-04-16 15:01:32

标签: node.js mongodb mongoose

我正在构建一个nodejs应用程序,它存储不同餐厅的菜单。架构如下 -

  var company = new Schema({
        company_name : String,
        categories : [category]
    });

  var category = new Schema({
        // id : Object,
        category_name : String,
        subCategories : [subCategory]
    });

    var subCategory = new Schema({
        subCategory_name : String,
        items : [item]

    });

    var item = new Schema({
        item : String,
        price : Number,
        currency : String

    });

module.exports = mongoose.model('Menu', company)

我在节点应用程序中有一个溃败,例如:

app.post("/:_company_id/:_category_id/:_sub_cat_id/", function(res,req){...})

使用上面的方法我想插入/更新项目,所以我该怎么做。

在进行研究时,我发现mongoose不支持嵌套数组更新。使用位置方法$示例categories.$.subCategories.$.items不能使用它,因为mongoose不支持此功能。

请帮我一些其他技巧/黑客可以帮助我更新它。谢谢。如果不是我必须转移到一些关系数据库。

1 个答案:

答案 0 :(得分:0)

更新嵌套数组非常简单,只需更新子类别文档并将子类别ObjectID推送到父文档即可。我把粗糙的步骤放在底部。以下是允许此操作的架构设置示例。

父类别可以包含对另一个模式的引用作为子类别。例如:

var companySchema = new Schema({
    company_name : String,
    categories : [{
        type: Schema.Types.Mongoose.ObjectId,
        ref: Category
    }]
 });

var categorySchema = new Schema({
    category_name : String,
    subCategories : //Similar to above to reference sub-categories
});

var category = Mongoose.Model('Category', categorySchema);

因此,实际使用子文档更新父模型的粗略步骤是:

  1. 查询并返回其回调的父文档...
  2. 查询并返回子文档/子文档。然后,
  3. 根据需要更新子文档(有关正确的方法,请参阅mongoose API)。现在,
  4. 将子文档的ObjectId(如果它没有准备就绪)推送到相应的父属性中。最后,
  5. 保存子文档和父文档。
  6. 这是一个淡化的例子。

    Company.findOne({company_name: "someUniqueCompanyName"}, function(err, foundCompany){
        if(err){
             console.log(err);
        }
        //This could also be a Category.create(...)
        Category.findOne({someProperty:"someUniqueValue"}, function(err, foundCategory){
            if(err){
                console.log(err);
            }
    
    
            foundCategory.name = "New Category Name"; //Update Category
            foundCategory.save(); //save category
    
            //if category doesn't exist in company then push it. More often 
            //than not you will be doing a Category.create and then pushing 
            //the newly created category into foundComapny
            foundCompany.categories.push(foundCategory._id);
            foundCompany.save();
        })
    })
    

    这真正允许你做的是填充 将来使用子文档ObjectId来创建这些父文档。

    关于填充:http://mongoosejs.com/docs/populate.html

    关于更新方法:http://mongoosejs.com/docs/api.html