我有一个comment
这样的集合
{
_id: 'c1',
text: 'comment 1',
votes: 1,
replies: [
{
_id: 'r1',
text: 'reply 1',
isReply: true,
votes: 3
},
{
_id: 'r2',
text: 'reply 2',
isReply: true,
votes: 0
}
]
},
{
_id: 'c2',
text: 'comment2',
votes: 2,
replies: []
}
这个想法是一个评论可以有很多回复。所有评论和回复都有 id ,文字,投票。如何获得最佳2条评论或回复最多投票。在给定的情况下,这将是“回复1”和“评论2”。
我可以向mongodb发送1个请求以获得最佳2条评论,另一个请求获得最佳2条回复,然后将它们进行比较以获得我想要的内容。
但是,只有1个mongodb请求才有可能,我可以得到这样的结果吗?
[
{
_id: 'r1',
text: 'reply 1',
isReply: true,
votes: 3
},
{
_id: 'c2',
text: 'comment 2',
votes: 2
}
]
或者我可以更好地展开评论/回复,以便按votes
排序评论或回复列表?
在这种情况下,它们的[r1,c2,c1,r2]分别具有其属性
感谢。
更新:
我尝试了aggregate({$unwind: '$replies'})
但我仍然有2个不同级别的评论和回复,我无法使用聚合框架进行比较。也许有一种方法可以压扁这两个级别,我对mongodb很新。
答案 0 :(得分:4)
对架构进行一点改动以使投票非规范化将使分类更容易。如果评论文档中嵌入了另一组投票,例如:
votes: [
{ "type" : "c", "_id": "c1", v: 1},
{ "type" : "r", "_id": "r1", v: 3},
{ "type" : "r", "_id": "r2", v: 2}
]
查询和排序可能很简单。
db.playground.aggregate(
[
{$project: { votes: 1 }},
{$unwind: "$votes"},
{$sort: {"votes.v": -1}},
{$limit: 2}
])
它给出了以下结果。
{
"result" : [
{
"_id" : "c1",
"votes" : {
"type" : "c",
"_id" : "c1",
"v" : 3
}
},
{
"_id" : "c1",
"votes" : {
"type" : "r",
"_id" : "r1",
"v" : 2
}
}
],
"ok" : 1
}
需要投票.v的索引,因为它看起来像是一个重读用例。更新注释时,只需在同一更新请求中更新votes数组。
答案 1 :(得分:0)
我建议你不要在评论对象中添加回复。 DbObject最大大小为16mb。如果评论有很多回复,这种结构就会失败。您可以在注释集合中保留回复,并将父注释ID放入回复对象(您可能希望放置{type:'reply'}或{type:'comment'}字段,而不是此结构,但parentCommentId将提供哪一个是什么类型)。通过这种方式,您可以轻松查询评论和回复。
我还想补充一点,聚合查询不适合UI响应。我不知道你的用例,但不要忘记它。