Специфичность Model.findOneAndRemove (MongoDB

#javascript #node.js #mongodb #mongoose #ejs

#javascript #node.js #mongodb #mongoose #ejs

Вопрос:

Я пытался создать свое первое сольное CRUD-приложение (не следуя руководству) и столкнулся с чем-то немного странным, что я не могу осознать. Прошу прощения, если это довольно очевидно, но я не смог найти здесь ничего по этому поводу.

Я добавил свой маршрут удаления для одной из моих моделей и использовал следующий код:

 // delete list
router.delete("/lists/:id", function(req, res){
    // find list by ID and remove it
    List.findOneAndRemove(req.params.id, function(err, deletedList){
        if(err) {
            console.log("ERROR DELETING LIST");
            console.log(err);
            res.redirect("/lists");
        } else {
            // if list is removed successfully, remove each item
            console.log(deletedList);
            Item.remove({_id: {$in: deletedList.items}}, function(err, deletedItems){
                if(err) {
                    console.log("ERROR DELETING ITEMS");
                    console.log(err);
                } else {
                    console.log("SUCCESSFULLY DELETED LIST amp; ALL ITEMS");
                    res.redirect("/lists");
                }
            });
        }
    });
});
  

Теперь он удаляет данные из базы данных, однако это не удаляет правильные вещи. На моей веб-странице есть кнопка, которая отправляет форму. Действие формы генерируется на основе содержимого страницы, где я вставляю идентификатор модели в действие с помощью EJS. Когда я отправляю форму для удаления модели и элементов, на которые даны ссылки, это приводит к удалению первого документа в базе данных, хотя (насколько я понимаю) я указал, что должны быть удалены только документы, соответствующие предоставленному идентификатору.

Я исправил это, заменив

 List.findOneAndRemove(req.params.id, function(err, deletedList){
            if(err) {
                console.log("ERROR DELETING LIST");
                console.log(err);
                res.redirect("/lists");
            } else {
  

с

 List.findOneAndRemove({_id: {$in: req.params.id}}, function(err, deletedList){
        if(err) {
            console.log("ERROR DELETING LIST");
            console.log(err);
            res.redirect("/lists");
        } else {
  

хотя я не совсем уверен, почему это работает и req.params.id не работает. Я просто надеялся на некоторые разъяснения на случай, если я столкнусь с чем-то подобным в будущем.

Ответ №1:

Я полагаю, что это удаляет первый элемент в вашем массиве, потому что вы используете «FindOneAndRemove» — как предлагается в названии, это ограничит совпадение одним документом. И в вашей первой версии кода:

 List.findOneAndRemove(req.params.id, function(err, deletedList){
  

Вы не указываете свое поле _id, поэтому я полагаю, что оно соответствует всему и удаляет только один документ из-за используемого вами метода. Где, как и во втором, вы находитесь

 List.findOneAndRemove({_id: {$in: req.params.id}}, function(err, deletedList){
  

Ответ №2:

Вот возможная причина, на которую я могу указать. Когда вы передаете req.params.id для findOneAndRemove, поскольку JS не является строго типизированным языком, и вы специально не вводите его, Mongoose не уверен, что нужно удалить.

Первым параметром для findOneAndRemove является объект filter, и Mongoose не может найти правильную фильтрацию, поскольку тип данных, который передается здесь, является строкой.

Я думаю, тогда Mongoose рассмотрит пустой фильтр, и, как обычно, пустой фильтр удаляет первый элемент. Одна из попыток, которую вы можете сделать, это явно ввести _id, скажем, как

 var id = new mongoose.mongo.ObjectID(req.params.id)
  

и передайте этот идентификатор функции findOneAndRemove().

Надеюсь, это поможет.

Комментарии:

1. Отлично, спасибо. Это отчасти ответило само собой, когда я провел еще немного тестирования, но это почти тот же вывод, к которому я пришел, прочитав немного больше. Я, вероятно, должен был провести немного больше исследований, я думаю. По крайней мере, я знаю, что в следующий раз!

2. Я рад, что это помогло. Если ваша проблема решена, пожалуйста, отметьте этот ответ одобренным, чтобы он помог другим людям, имеющим тот же опыт. Спасибо.