2017-04-15 135 views
2

考慮這樣的模式:更新雙重嵌套數組的MongoDB

let userSchema = new mongoose.Schema({ 
id: String, 
displayName: String, 
displayImage: String, 
posts: [ 
    { 
     url: String, 
     description: String, 
     likes: [String], 
     comments: [ 
      { content: String, date: String, author: { id: String, displayName: String, displayImage: String } } 
     ] 
    } 
] 
}); 

我能夠使用此查詢

controller.deleteComment = (req, res, next) => { 
User.findOneAndUpdate(
    { id: req.query.userid, 'posts._id': req.params.postid, }, 
    { 
     $pull: { 
      'posts.$.comments': { _id: req.body.commentID }, 
     } 
    } 
) 
    .exec() 
    .then(() => { 
     res.send('deleted'); 
    }) 
    .catch(next); 
}; 

來刪除評論陣列某一項反正是有,我可以更新評論數組通過使用$set運算符?我需要根據其評論ID來改變註釋的內容..是這樣的:

controller.editComment = (req, res, next) => { 
    User.findOneAndUpdate(
     { id: req.query.userid, 'posts._id': req.params.postid, 'comments._id':req.body.commentID }, 
     { 
      $set: { 
       'posts.$.comments': { content: req.body.edited }, 
      } 
     } 
    ) 
     .exec() 
     .then(() => { 
      res.send('deleted'); 
     }) 
     .catch(next); 
}; 

這^顯然是不工作,但我不知道是否有一種方法可以讓我做到這一點?

UPDATE 根據以下建議,我正在做以下事項來管理只有一個架構。這是有效的,但是無論我正在編輯哪些帖子評論,只有第一篇文章的評論得到更新。我已經檢查過,退貨文件總是正確的。 doc.save()方法必定存在問題。

controller.editComment = (req, res, next) => { 
User.findOne(
    { id: req.query.userid, 'posts._id': req.params.postid }, 
    { 'posts.$.comments._id': req.body.commentID } 
) 
    .exec() 
    .then((doc) => { 
     let thisComment = doc.posts[0].comments.filter((comment) => { return comment._id == req.body.commentID; }); 
     thisComment[0].content = req.body.edited; 
     doc.save((err) => { if (err) throw err; }); 
     res.send('edited'); 
    }) 
    .catch(next); 
}; 

回答

2

我不知道一個簡單的(甚至是艱難的:P)的方式來達到什麼正在嘗試做的。在mongo中,在雙重嵌套陣列中操作相對困難,因此最好避免。

如果您仍然對模式更改開放,我建議您爲註釋創建不同的模式並在用戶模式內引用該模式。

所以,您的評論架構將是這樣的:

let commentSchema = new mongoose.Schema({ 
    content: String, 
    date: String, 
    author: { 
      id: String, 
      displayName: String, 
      displayImage: String 
    } 
}); 

而且你的用戶模式應該是這樣的:

let userSchema = new mongoose.Schema({ 
    id: String, 
    displayName: String, 
    displayImage: String, 
    posts: [{ 
     url: String, 
     description: String, 
     likes: [String], 
     comments: [{ 
      type: Schema.Types.ObjectId, 
      ref: 'comment' //reference to comment schema 
     }] 
    }] 
}); 

這樣,你的數據操作會方便很多。獲取用戶文檔時您可以註釋populate。並且,請注意更新/刪除操作是多麼容易,因爲您已經知道要更新的評論的_id。

希望你找到這個答案有幫助!

+0

可能是一個好主意,通過發佈帖子進一步分解它。 – Mikey

+0

我明白了,但我最初只想用一個Schema來完成這個項目(可能是因爲我瘋了),有沒有辦法只用一個Schema來做到這一點? – JohnSnow

+0

是的,可以在一個模式中管理它。在這種情況下,您將不得不運行for循環,並將'comments'數組中的每個對象的'_id'與'req.body.commentID'匹配。這很討厭,但如果陣列的長度很小,你會好的。 –

-3
controller.editComment = (req, res, next) => { 
    User.findOneAndUpdate(
     { id: req.query.userid, 'posts._id': req.params.postid, 'comments._id':req.body.commentID }, 
     { 
      $push: { 
       'posts.$.comments': { content: req.body.edited }, 
      } 
     } 
    ) 
     .exec() 
     .then(() => { 
      res.send('deleted'); 
     }) 
     .catch(next); 
}; 
+0

我想替換一個評論,而不是推入新的評論 – JohnSnow