在我的项目中,我想实现一个由评论列表组成的评论部分。
const myschema= mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
//other fields
comments : [comment]
},{collection : 'TABLE_NAME'} );
const comment= mongoose.Schema({
_id : mongoose.Schema.Types.ObjectId,
commentid: String, // id consists of uuid1()
senderid: Number, //user's id
body: String, // useful information
parent: String,// parent id consists of uuid1()
children: [] // I couldn't add children = [comment], it gives me an error,
//instead, I make it empty and will fill it when a comment comes
})
在请求标签中,我将收到以下格式的JSON:
{
"userid": "NUMBERID HERE",
"comment": "COMMENT BODY",
"parent" : "Comment's parent id"
}
我想添加一条评论,它可以是另一条评论的子项。如何搜索并找到合适的位置?
如果JSON主体中没有父级,我正在这样做:
// import comment somewhere at the beginning
.then(doc =>{
var newc= new comment();
newc.cid = uuidv1();
newc.sender = req.body.userid;
newc.body = req.body.comment;
newc.parent = "";
newc.children = "";
doc.comments.push(newc);
// save to DB
doc
.save()
.then(docres =>{
res.status(200).json(docres);
})
.catch(err => {
res.status(500).json({error: err});
})
}
我不知道如何找到深入的评论
答案 0 :(得分:0)
不能给定未指定的,任意嵌套的深度的数组元素或对象属性。只是不可能。您将需要在应用程序层中进行处理。对数据进行非规范化在很多情况下都可以,但是建议不要将任意嵌套深度用于数据非规范化,尤其是因为您无法有效地建立索引!
如果您想要一个纯MongoDB解决方案,那么您将需要一个不同的文档结构。我建议您看一下documentation,尤其是有关array of ancestors的部分,以便正确地对数据建模。
答案 1 :(得分:0)
我找到了解决方法。
手动遍历注释并在正确的位置插入即可。但是,它只能在一定程度上起作用。就我而言,我可以在评论下方插入评论并保存。我还可以插入第3个深度注释,并查看我插入的对象的JSON转储,甚至将其包装在HTTP响应对象中并发送给客户端。但是数据库不会保存此更新。
我要做的是,在正确的位置插入注释之后,我在保存到数据库之前添加了此代码。
doc.markModified('comments'); // this is added
doc.save().then(/*prepare response*/);
以某种方式,MongoDB或mongoose或javascript解释器知道文档已更改并保存更新的版本。如果未指定markmodified
部分,则编译器可能认为该对象尚未修改,因此跳过该对象。
希望这对遇到此问题的人有所帮助。 这是我的实现
// find the document which comment is going to be inserted
MyDOC.findOne({'id' : req.params.id})
.exec()
.then(doc =>{
// if the comment has a parent, it should be inserted in nested
if(req.body.parent != null && req.body.parent != undefined)
{
// find correct position and insert
findComment(doc.comments, req.body);
doc.markModified('comments');
doc
.save()
.then(docres =>{
res.status(200).json(docres);
})
.catch(err => {
console.log(err);
res.status(500).json({error: err});
})
}
else
{
//Add comment to the root level
var comment= new Comment();
comment.cid = uuidv1();
comment.body = req.body.comment;
comment.parent = "";
doc.comments.push(comment);
doc.markModified('comments');
// save to DB
doc
.save()
.then(docres =>{
res.status(200).json(docres);
})
.catch(err => {
console.log(err);
res.status(500).json({error: err});
})
}
})
function findComment(comment, body)
{
comment.forEach(element => {
if(element.children.length != 0)
{
if(element.cid === body.parent)
{
// found, insert
var comment= new Comment();
comment.cid = uuidv1();
comment.body = body.comment;
comment.parent = body.parent;
element.children.push(comment);
return true;
}
if(findComment(element.children, body, usr))
return true;
}
else
{
// this comment does not have children. If this comments id and the body's parent is equal, add it
if(element.cid === body.parent)
{
// found, insert
var comment= new Comment();
comment.cid = uuidv1();
comment.body = body.comment;
comment.parent = body.parent;
element.children.push(comment);
return true;
}
return false;
}
});
}