#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. Я рад, что это помогло. Если ваша проблема решена, пожалуйста, отметьте этот ответ одобренным, чтобы он помог другим людям, имеющим тот же опыт. Спасибо.