2012-11-02 1 views
7

集計フレームワークを使用すると、グループ単位でフィールドの最大値を持つ文書を取得する最良の方法は、最新の日付を持つgroup_idごとに1つのドキュメントを返す機能を持つようにします。 2番目のリストは、望ましい結果を示しています。フィールド単位で集計し、別のフィールドの最大値をコレクションとして選択して文書を選択する

group_id date 
1  11/1/12 
1  11/2/12 
1  11/3/12 
2  11/1/12 
3  11/2/12 
3  11/3/12 

望ましい結果

group_id date 
1  11/3/12 
2  11/1/12 
3  11/3/12 
+3

[あなたは何を試してみました?](http://whathaveyoutried.com) – JohnnyHK

+0

私は、これはあなたが探していたかなりものではありません知っているが、あなたは反復可能性グループIDを使用して次のようにします。 db.foo.find({group_id:n}).sort({date:-1}).limit(1) - 各group_id = nに対して。 これは、指定されたグループidを持つすべてのドキュメントを日付順に並べ替え、最新のものだけを返します。 – Louisa

答えて

6

あなたは、各group_idの最新のドキュメントを見つけるために、集約フレームワークで$maxのグループ化機能を使用することができます。グループ化された条件に基づいて完全なドキュメントを取得するには、追加のクエリが必要です。

var results = new Array(); 
db.groups.aggregate(
    // Find documents with latest date for each group_id 
    { $group: { 
     _id: '$group_id', 
     date: { $max: '$date' }, 
    }}, 
    // Rename _id to group_id, so can use as find criteria 
    { $project: { 
     _id: 0, 
     group_id:'$_id', 
     date: '$date' 
    }} 
).result.forEach(function(match) { 
    // Find matching documents per group and push onto results array 
    results.push(db.groups.findOne(match)); 
}); 

例の結果:

{ 
    "_id" : ObjectId("5096cfb8c24a6fd1a8b68551"), 
    "group_id" : 1, 
    "date" : ISODate("2012-11-03T00:00:00Z"), 
    "foo" : "bar" 
} 
{ 
    "_id" : ObjectId("5096cfccc24a6fd1a8b68552"), 
    "group_id" : 2, 
    "date" : ISODate("2012-11-01T00:00:00Z"), 
    "foo" : "baz" 
} 
{ 
    "_id" : ObjectId("5096cfddc24a6fd1a8b68553"), 
    "group_id" : 3, 
    "date" : ISODate("2012-11-03T00:00:00Z"), 
    "foo" : "bat" 
} 
+0

ありがとうございます。どうすれば最大の日付を持つドキュメント全体として取得できますか?グループ化した後にプロジェクトを行い、すべてのフィールドを明示的に取得する必要がありますか? – user1795267

+0

グループ化すると、おそらくあなたが意図していないドキュメントが結合されます。最新のドキュメント '_id'を見つけるために集約フレームワークを使い、完全なドキュメントをフェッチするために' $ in'クエリを使うようにサンプルを更新しました。 – Stennie

+2

@Stennieありがとう、これは素晴らしいです!しかし、$ maxのIDの選択は、$ maxの日付を持つdocのidではなく、最も高い_idを選択するべきではありませんか?ここで注文は問題ですか? – Timothy055

関連する問題