Mongoose findOne встроенный документ от _id

Я пытаюсь нажать меню во встроенный документ. Но в ресторане я не нашел 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);
            });
        }
    });
}

Ответ 1

Поддокументы имеют метод .id(), поэтому вы можете сделать это:

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

См. http://mongoosejs.com/docs/subdocs.html для справки.

Ответ 2

restaurant - это просто объект, содержащий результат для вашего запроса. Он не имеет метода findOne, только restaurant делает.

Так как MenuCategory - это всего лишь суб-документ restaurant, это будет происходить с заполнением, когда вы будете получать ресторан. Например.

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 - мышление несколько отличается. Вот некоторые ссылки на некоторые SO-вопросы об эффективном проектировании схем с базами данных NoSQL: