Mongoose: findByIdAndRemove и forEach не работают в объекте вложенного массива - PullRequest
0 голосов
/ 23 сентября 2019

Проблема 1 : у меня есть Модель с массивом объектов, и один объект содержит несколько объектов. Я хочу удалить основной объект с помощью findByIdAndRemove, но связанный объект не был удален.Кто-нибудь может дать мне какую-нибудь подсказку, чтобы я мог ее решить?
blogSchema

var blogSchema=new mongoose.Schema({
    title:String,
    image:String,
    body:{type:String, default:""},
    created:{ type: Date },
  comments:[{
    type:mongoose.Schema.Types.ObjectId,
    ref:'Comment'
  }]
});

commentSchema

var commentSchema=mongoose.Schema({
    text:String,
    author:String
})

Вот чтоЯ попытался:

app.delete('/blogs/:id',function(req,res,next){
    //destroy blog
    Blog.findByIdAndRemove(req.params.id,function(err){
        if(err){
            res.redirect('/blogs')
        }else{
            res.redirect('/blogs')
        }
    })
})

Но он удаляет только мой блог , а не комментарии , связанные с блогом.
Проблема 2 : одна небольшая проблема в /blogs/:id при рендеринге show.ejs./blogs/:id GET выбирает только один блог с соответствующими комментариями.если я закодировал <%=blog.comments%> в show.ejs, то он возвращает

 { author: 'emon ', text: 'comment 1', _id: 5d87027848e59703a4d4a935, __v: 0 },
{ author: 'emon ', text: 'comment 2\r\n', _id: 5d87028848e59703a4d4a936, __v: 0 } 

, что означает, что он отлично работает, но если я закодировал:

<%blog.comments.forEach(function(comment)%>
<p><strong><%=comment.author%></strong>-<%=comment.text%></p>
)%>

, это даст мне SyntaxError .
Полная ошибка :

    SyntaxError: Unexpected token ; in C:\Users\websi\OneDrive\Desktop\Project\RESTfulBlogApp\v3\views\blogs\show.ejs while compiling ejs

If the above error is not helpful, you may want to try EJS-Lint:
https://github.com/RyanZim/EJS-Lint
Or, if you meant to create an async function, pass async: true as an option.
    at new Function (<anonymous>)
    at Template.compile (C:\Users\websi\OneDrive\Desktop\Project\RESTfulBlogApp\v3\node_modules\ejs\lib\ejs.js:633:12)
    at Object.compile (C:\Users\websi\OneDrive\Desktop\Project\RESTfulBlogApp\v3\node_modules\ejs\lib\ejs.js:392:16)
    at handleCache (C:\Users\websi\OneDrive\Desktop\Project\RESTfulBlogApp\v3\node_modules\ejs\lib\ejs.js:215:18)
    at tryHandleCache (C:\Users\websi\OneDrive\Desktop\Project\RESTfulBlogApp\v3\node_modules\ejs\lib\ejs.js:254:16)
    at View.exports.renderFile [as engine] (C:\Users\websi\OneDrive\Desktop\Project\RESTfulBlogApp\v3\node_modules\ejs\lib\ejs.js:485:10)
    at View.render (C:\Users\websi\OneDrive\Desktop\Project\RESTfulBlogApp\v3\node_modules\express\lib\view.js:135:8)
    at tryRender (C:\Users\websi\OneDrive\Desktop\Project\RESTfulBlogApp\v3\node_modules\express\lib\application.js:640:10)
    at Function.render (C:\Users\websi\OneDrive\Desktop\Project\RESTfulBlogApp\v3\node_modules\express\lib\application.js:592:3)
    at ServerResponse.render (C:\Users\websi\OneDrive\Desktop\Project\RESTfulBlogApp\v3\node_modules\express\lib\response.js:1012:7)
    at C:\Users\websi\OneDrive\Desktop\Project\RESTfulBlogApp\v3\app.js:77:8
    at C:\Users\websi\OneDrive\Desktop\Project\RESTfulBlogApp\v3\node_modules\mongoose\lib\model.js:4616:16
    at C:\Users\websi\OneDrive\Desktop\Project\RESTfulBlogApp\v3\node_modules\mongoose\lib\utils.js:264:16
    at C:\Users\websi\OneDrive\Desktop\Project\RESTfulBlogApp\v3\node_modules\mongoose\lib\query.js:4320:11
    at C:\Users\websi\OneDrive\Desktop\Project\RESTfulBlogApp\v3\node_modules\kareem\index.js:135:16
    at processTicksAndRejections (internal/process/task_queues.js:75:11)

Будем благодарны за любую помощь.Извините, что задали слишком много вопросов в одном.Спасибо за ваше время.
Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 23 сентября 2019

Для Задачи 1: Поскольку MongoDB не является реляционной БД, для нее нет встроенной функции.Вы должны удалить все комментарии блога, выполнив запрос, и для этого вам необходимо соответствующим образом создать схему комментариев.

Если вы используете mongoose ODM, вы можете попробовать промежуточное программное обеспечение mongoose, чтобы уменьшить ваши усилия для предопределенныхзапросы

https://mongoosejs.com/docs/middleware.html

, но вам необходимо соответствующим образом управлять схемой, чтобы можно было найти все необходимые комментарии

Для задачи 2: Предоставить ееПопробуйте

<% for(var i=0; i<blog.comments.length; i++) {%> <p><strong><%=blog.comments[i].author%></strong>-<%=blog.comments[i].text%></p>> <% } %>
1 голос
/ 24 сентября 2019

Вы можете использовать предварительный крючок мангуста, например,

blogSchema.pre('remove', function(next) {
    Comment.remove({author: this._id}).exec(); // Comment model
    next();
});

Подробнее https://mongoosejs.com/docs/middleware.html#pre

Вот рабочий пример кода https://github.com/arifmahmudrana/task-api/blob/master/src/models/User.js#L158-L168

Это должно работать

const mongoose = require('mongoose'); // import mongoose
const Schema = mongoose.Schema; // extract schema for easy use

// declare blogSchema
const blogSchema = new Schema({
  title: String,
  image: String,
  body: { type: String, default: '' },
  created: { type: Date },
  comments: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Comment'
    }
  ]
});

const Blog = mongoose.model('Blog', blogSchema); // Blog model

const commentSchema = Schema({
  text: String,
  author: String
});
const Comment = mongoose.model('Comment', commentSchema); // Comment model
blogSchema.pre('remove', function(next) {
  Comment.remove({ author: this._id }).exec(); // Comment model
  next();
});

module.exports = { Blog, Comment };

// Now import Blog here
app.delete('/blogs/:id', function(req, res, next) {
  //destroy blog
  Blog.findByIdAndRemove(req.params.id, function(err) {
    if (err) {
      res.redirect('/blogs');
    } else {
      res.redirect('/blogs');
    }
  });
});
...