2016-10-18 3 views
0

私はこのようなコレクションを持っている:私はすべてのフィールドのために(フィールドdateに基づいて)その最新の値を返す、単一の手順を実行したいと思いますのMongoDB:すべてのフィールドの最新の値

{ 
    _id : 1, 
    key : "one", 
    date : ISODate("2016-10-18 08:00.000"), 
    a : "a1", 
    b : "b1" 
}, 
{ 
    _id : 2, 
    key : "two", 
    date : ISODate("2016-10-18 09:00.000"), 
    a : "a2", 
    b : "b2" 
}, 
{ 
    _id : 3, 
    key : "one", 
    date : ISODate("2016-10-18 10:00.000"), 
    b : "b3", 
    c : "c3" 
}, 
{ 
    _id : 4, 
    key : "one", 
    date : ISODate("2016-10-18 11:00.000"), 
    b : "b4" 
} 

を、私はgroupsortmatchを使用して、多くのaggregateと試みたが、している

{ 
    _id : "one", 
    a : "a1", 
    b : "b4", 
    c : "c3" 
}, 
{ 
    _id : "two", 
    a : "a2", 
    b : "b2" 
} 

:そう、前の収集のために、私はこの結果を受け取ることになります最新の値がgroup、ステージ後の新しい配列の最初の要素になりますので、成功アウト...あなたがする必要がどのような

+0

予想される結果は正しいですか? – NEER

+0

@NEER、申し訳ありませんが、期待された結果が間違っていました。ありがとうございました。 – Michele

+0

あなたは 'key'値でグループ分けしていますか?投影フィールドは動的ですか?または常に同じでしょうか? – TomG

答えて

3

date、その後group$push値によってsortた文書です。その後、$projectステージで最新の値を表示するには$arrayElemAtを使用してください。配列が空の場合(例:key: twoのように)、値は期待した結果として投影されません。あなた例えば、それは次のようになります:

db.test.aggregate([ 
    { 
     $sort: { 
      date: -1 
     } 
    }, 
    { 
     $group: { 
      _id: '$key', 
      a: {$push: '$a'}, 
      b: {$push: '$b'}, 
      c: {$push: '$c'} 
     } 
    }, 
    { 
     $project: { 
      a: {$arrayElemAt: ['$a', 0]}, 
      b: {$arrayElemAt: ['$b', 0]}, 
      c: {$arrayElemAt: ['$c', 0]} 
     } 
    } 
]) 

このソリューションの唯一の問題は、あなたが持っているフィールドの名前を知っているということです。利用可能なすべてのフィールドでそれを行う「汎用」集約を行うことはできません。可能なフィールドを知っていれば、それは問題ではありません。 mongooseなどを使用している場合は、aggregate関数を呼び出す前にjavascriptを使用して$group$projectのステージを構築するには、schemaを使用します。

+0

私はあなたのソリューションを使用しました。 – Michele

+0

@Micheleさん、ありがとうございました。 :) – TomG

+0

@トムグ、私は少し待って誰か他の人が答え...しかしあなたが勝つ:) – Michele

関連する問題