Mongoose通过_id查找一个嵌入文档

时间:2013-12-17 08:18:56

标签: node.js mongodb mongoose

我正在尝试将菜单推送到嵌入式文档。但是我在餐厅里没有定义findOne。我只想将一些文件推入餐厅的菜单类别。正如您在架构中看到的那样:

var RestaurantSchema = new mongoose.Schema({
    contactTelphone : String,
    address : String,
    branchID : String,
    email : String,
    restaurantName : String,
    userID : String,
    menuCategory : [MenuCategorySchema]
});

var MenuCategorySchema = new mongoose.Schema({
    menuCategory : String,
    menuCategoryAlt : String,
    sequence : Number,
    menus : [MenuSchema],
    restaurantInfo : { type: Schema.Types.ObjectId, ref: 'Restaurant' },
});

var MenuSchema = new mongoose.Schema({
    foodName : String,
    foodNameAlt : String,
    picName : String,
    price : String,
    rating : Number,
    menuSequence : Number,
    category : { type: Schema.Types.ObjectId, ref: 'MenuCategory' },
});

exports.menuForMenuCategory = function(newData, callback)
{
    console.log(newData);

    var menuCategoryId = newData.menuCategoryId;
    var restaurantId = newData.restaurantId;

    var newMenu = new Menu({
        foodName : newData.foodName,
        foodNameAlt : newData.foodNameAlt,
        picName : newData.picName,
        price : newData.price,
        cookingCategory : newCookingCategory,
        dishSpecial : newDishSpeical
    });

    Restaurant.findOne( {'_id' : restaurantId }, function(err, restaurant){
        if (!err) {
                    //Is it how to do this? It says "findOne not defined"
            restaurant.findOne( "_id" : menuCategoryId, function(err, category){
                category.push(newMenu);
            });
        }
    });
}

2 个答案:

答案 0 :(得分:24)

子文档有一个.id()方法,所以你可以这样做:

myModel.findById(myDocumentId, function (err, myDocument) {
  var subDocument = myDocument.mySubdocuments.id(mySubDocumentId);
});

请参阅http://mongoosejs.com/docs/subdocs.html以供参考。

答案 1 :(得分:3)

restaurant只是一个包含查询结果的对象。它没有findOne方法,只有Restaurant

由于MenuCategory只是Restaurant的子文档,因此无论何时检索餐馆,都会预先填充此文件。 E.g。

Restaurant.findById(restaurantId, function(err, restaurant){
    console.log(restaurant.menuCategory);  
    // Will show your array of Menu Categories
    // No further queries required
});

添加新的菜单类别是将新MenuCategory实例推送到menuCategory数组并保存餐馆的问题。这意味着新菜单类别与餐馆一起保存,而不是单独的集合。例如:

Restaurant.findById(restaurantId, function(err, restaurant){
    // I'm assuming your Menu Category model is just MenuCategory
    var anotherMenuCategory = new MenuCategory({
        menuCategory: "The name",
        menuCategoryAlt: "Alternative name",
        sequence: 42,
        menus: []
    });
    restaurant.menuCategory.push(anotherMenuCategory);
    restaurant.save(); // This will save the new Menu Category in your restaurant
});

将菜单保存到菜单类别遵循相同的步骤,因为根据您的架构,菜单是每个MenuCategory中的嵌入子文档。但请注意,您需要将餐厅保存为将所有菜单和菜单类别存储为子文档的餐馆集合

回答了你的问题(我希望)后,我还应该指出你的架构设计应该重新思考。将子文档嵌套在子文档中可能不是一个好主意。我想我可以看到你来自哪里 - 你正试图在你的模式中实现类似SQL的多对一关联。但这对于NoSQL数据库来说并不是必需的 - 思路有些不同。以下是一些关于使用NoSQL数据库进行高效架构设计的SO问题的链接: