19

ユーザーが独自のブログを作成できるブログ プラットフォームに mongodb を使用しています。すべてのブログのすべてのエントリがエントリ コレクションに含まれています。エントリのドキュメントは次のようになります。

{
  'blog_id':xxx,
  'timestamp':xxx,
  'title':xxx,
  'content':xxx
}

質問が示すように、各ブログの最後の 3 つのエントリを選択する方法はありますか?

4

5 に答える 5

29

最初にコレクション内のドキュメントをblog_idおよびtimestampフィールドで並べ替え、次に元のドキュメントの配列を降順で作成する初期グループを実行する必要があります。その後、配列をドキュメントでスライスして、最初の 3 つの要素を返すことができます。

この例では、直感に従うことができます。

db.entries.aggregate([
    { '$sort': { 'blog_id': 1, 'timestamp': -1 } }, 
    {       
        '$group': {
            '_id': '$blog_id',
            'docs': { '$push': '$$ROOT' },
        }
    },
    {
        '$project': {
            'top_three': { 
                '$slice': ['$docs', 3]
            }
        }
    }
])
于 2017-01-07T22:25:37.973 に答える
1

別の質問からのdrcostaによるmap reduceを使用したこの回答は、うまくいきました

mongoでは、map reduceを使用してグループを最新順に並べ替えるにはどうすればよいですか

mapper = function () {
  emit(this.category, {top:[this.score]});
}

reducer = function (key, values) {
  var scores = [];
  values.forEach(
    function (obj) {
      obj.top.forEach(
        function (score) {
          scores[scores.length] = score;
      });
  });
  scores.sort();
  scores.reverse();
  return {top:scores.slice(0, 3)};
}

function find_top_scores(categories) {
  var query = [];
  db.top_foos.find({_id:{$in:categories}}).forEach(
    function (topscores) {
      query[query.length] = {
        category:topscores._id,
        score:{$in:topscores.value.top}
      };
  });
  return db.foo.find({$or:query});
于 2011-12-25T03:49:53.530 に答える
1

2つのことで生活できる場合、基本的なmongoでこれを行う唯一の方法:

  • エントリー書類の追加フィールド、「年齢」としましょう
  • 追加の更新を行う新しいブログエントリ

その場合は、次のようにします。

  1. 新しいイントロを作成したら、通常の挿入を行ってから、この更新を実行して、すべての投稿 (このブログに挿入したものを含む) の年齢を上げます。

    db.entries.update({blog_id: BLOG_ID}, {age:{$inc:1}}, false, true)

  2. クエリを実行するときは、ブログごとに最新の 3 つのエントリを返す次のクエリを使用します。

    db.entries.find({age:{$lte:3}, timestamp:{$gte:STARTOFMONTH, $lt:ENDOFMONTH}}).sort({blog_id:1, age:1})

このソリューションは、実際には同時実行に対して安全であることに注意してください (年齢が重複するエントリはありません)。

于 2011-06-28T13:53:52.513 に答える
0

グループ (集計) で可能ですが、これによりテーブル全体のスキャンが作成されます。

本当に正確に 3 つ必要ですか、それとも制限を設定できますか? 例: 先週/月から最大 3 つの投稿?

于 2011-06-27T21:42:01.627 に答える