更新双层嵌套数组 MongoDB
Updating a double nested array 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
运算符更新 comments 数组中的元素?我需要根据评论 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);
};
这个 ^ 显然不起作用,但我想知道是否有办法做到这一点?
更新
根据下面的建议,我正在执行以下操作以仅管理一个架构。这有效,但是只有第一个 post 的评论得到更新,无论我正在编辑哪个 post 的评论。我检查过 return 文档总是正确的。 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);
};
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);
};
我不知道实现目标的简单(甚至是困难的 :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 在获取用户文档时发表评论。而且,请注意 update/delete 操作是多么简单,因为您已经知道要更新的评论的 _id。
希望此回答对您有所帮助!
考虑这个模式:
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
运算符更新 comments 数组中的元素?我需要根据评论 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);
};
这个 ^ 显然不起作用,但我想知道是否有办法做到这一点?
更新
根据下面的建议,我正在执行以下操作以仅管理一个架构。这有效,但是只有第一个 post 的评论得到更新,无论我正在编辑哪个 post 的评论。我检查过 return 文档总是正确的。 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);
};
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);
};
我不知道实现目标的简单(甚至是困难的 :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 在获取用户文档时发表评论。而且,请注意 update/delete 操作是多么简单,因为您已经知道要更新的评论的 _id。
希望此回答对您有所帮助!