Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose findOne embedded document by _id

I am trying to push menus to the embedded document. But I am getting not defined findOne in restaurant. I just want to push some documents into the restaurant's menu categories. As you can see in the schema:

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);
            });
        }
    });
}
like image 645
yong ho Avatar asked Dec 17 '13 08:12

yong ho


2 Answers

Subdocuments have an .id() method so you can do this:

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

See http://mongoosejs.com/docs/subdocs.html for reference.

like image 65
Paul Verhoeven Avatar answered Sep 29 '22 17:09

Paul Verhoeven


restaurant is just an object containing the result to your query. It does not have a findOne method, only Restaurant does.

Since, MenuCategory is just a sub-document of Restaurant, this will come pre-populated whenever you retrieve a restaurant. E.g.

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

Adding a new Menu Category is a matter of pushing a new MenuCategory instance to the menuCategory array and saving the restaurant. This means the new menu category is saved with the restaurant and not in a separate collection. For example:

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

Saving a menu to a menu category follows the same procedure since, according to your schema, Menus are embedded sub-documents within each MenuCategory. But note that you need to save the restaurant as its the restaurant collection that is storing all your menus and menu categories as sub-documents

Having answered your question (I hope) I should also point out your schema design should be rethought. Having sub-documents nested within sub-documents is arguably not a good idea. I think I can see where you're coming from - you're trying to implement a SQL-like many-to-one association within your schemas. But this isn't necessary with NoSQL databases - the thinking is somewhat different. Here are some links to some SO questions about efficient schema design with NoSQL databases:

like image 40
C Blanchard Avatar answered Sep 29 '22 19:09

C Blanchard