mongodb获取具有最高价值的文档/子文档

时间:2013-09-15 23:44:42

标签: mongodb aggregation-framework

我有一个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很新。

2 个答案:

答案 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响应。我不知道你的用例,但不要忘记它。