状況
特定の MongoDb クエリを実行するための良い方法を思いつくのに苦労しています。まず、これが私がやりたいクエリの種類です。電子カードのスワイプによって、入場イベントと退場イベント (および場合によっては他のアクションは重要ではない) をログに記録する単純なデータベースを想定します。したがって、次のswipelog
ような単純なドキュメントで呼び出されるコレクションがあります。
{
_id: ObjectId("524ab4790a4c0e402200052c")
name: "John Doe",
action: "entry",
timestamp: ISODate("2013-10-01T1:32:12.112Z")
}
ここで、名前とその最終エントリ時刻をリストしたいと思います (その他の必要なフィールドもありますが、以下の例ではこれら 2 つのフィールドのみを使用しています)。
現在のソリューション
MongoDb JavaScript コンソールの「ワンライナー」として、私が今持っているものを次に示します。
db.swipelog.distinct('name')
.forEach( function(name) {
db.swipelog.find( { name: name, action:"entry" } )
.sort( { $natural:-1 } )
.limit(1)
.forEach( function(entry) {
printjson( [ entry.name, entry.timestamp ] )
})
})
次のようなものが出力されます。
[ "John Doe", ISODate("2013-10-01T1:32:12.112Z")]
[ "Jane Deo", ISODate("2013-10-01T1:36:12.112Z")]
...
質問
上記には明らかなスケーリングの問題があると思います。100 個の名前がある場合、データベースに対して 1+100 個のクエリが実行されます。timestamp
では、「すべての個別の最後」を取得するための良い/正しい方法は何name
ですか? データベース構造を変更したり、いくつかのコレクションを追加したりすることは、これが簡単になる場合は問題ありません。