3

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: []
}

アイデアは、コメントが多くの返信を持つことができるということです。すべてのコメントと返信には、 idtextvoteがあります。投票数が最も多い最高の 2 つのコメントまたは返信を取得するにはどうすればよいですか。この場合、これは「返信 1」と「コメント 2」になります。

mongodb に 1 つの要求を送信して、最良の 2 つのコメントを取得し、別の要求を送信して最良の 2 つの返信を取得し、それらを比較して必要なものを取得できます。

しかし、mongodb への 1 つのリクエストだけで、このような結果が得られる可能性はありますか?

 [
   {
     _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 つの異なるレベルにコメントと返信がまだあります。これらの 2 つのレベルを平坦化する方法があるかもしれませんが、私は mongodb を初めて使用します。

4

2 に答える 2

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
}

読み取り負荷の高いユース ケースのように見えるため、votes.v のインデックスが必要です。コメントを更新するときは、同じ更新リクエストで投票配列を更新するだけです。

于 2013-09-16T16:30:23.180 に答える