2

毎分保存される新しいドキュメントの数に関する統計を作成したいと考えています。

標準の ObjectID を持つ _id フィールドには、ドキュメント作成のタイムスタンプが既に含まれているため、何らかの形で使用できるはずです。

Stackoverflow で、作成データ専用のフィールドがある場合に実行する次のマップ削減コードを見つけました

Map-Reduce 毎分のドキュメント数 MongoDB

map = function() {

var created_at_minute = new Date(this.created_at.getFullYear(),
                                 this.created_at.getMonth(), 
                                 this.created_at.getDate(), 
                                 this.created_at.getHours(), 
                                 this.created_at.getMinutes());
    emit(created_at_minute, {count: 1});
}

reduce = function(key, values) { 
         var total = 0;
         for(var i = 0; i < values.length; i++) { total += values[i].count; }
         return {count: total};
}

Mongo DB ドキュメント ( http://docs.mongodb.org/manual/reference/object-id/ ) によると、ObjectId("507f191e810c19729de860ea").getTimestamp() を呼び出すことで、_id からタイムスタンプを取得できるはずです。

今のところ、マップ関数内でこの getTimestamp() を使用できるかどうかはわかりません。

誰かがそれを行う方法を知っていますか、それともより良い方法がありますか?

Pythonまたはphpで実装できるようにする必要があります

4

1 に答える 1

4

これは実際に M/R で行うことができます。getTimestamp()サーバー上の JavaScript で実行されるため、M/R で動作します。クライアント言語が PHP であるか Python であるかは関係ありません。

map = function() {
    var datetime = this._id.getTimestamp();

    var created_at_minute = new Date(datetime.getFullYear(),
                                     datetime.getMonth(),
                                     datetime.getDate(),
                                     datetime.getHours(),
                                     datetime.getMinutes());
    emit(created_at_minute, {count: 1});
}

reduce = function(key, values) {
    var total = 0;
    for(var i = 0; i < values.length; i++) { total += values[i].count; }
    return {count: total};
}

db.so.mapReduce( map, reduce, { out: 'inline' } );
db.inline.find();

次のような出力が得られます。

{ "_id" : ISODate("2013-08-05T15:24:00Z"), "value" : { "count" : 9 } }
{ "_id" : ISODate("2013-08-05T15:26:00Z"), "value" : { "count" : 2 } }

ただし、 M/R を使用するのではなく、インデックスを使用して同時に実行できるため、はるかに高速な集計フレームワークを使用することをお勧めします。現時点では、A/F にはObjectIDフィールドからタイムスタンプを取得する演算子がまだありません。そのため、挿入時に時刻も保存する必要があります次のようなドキュメントを含む Fe:

db.so.drop();
db.so.insert( { date: new ISODate( "2013-08-05T15:24:15" ) } );
db.so.insert( { date: new ISODate( "2013-08-05T15:24:19" ) } );
db.so.insert( { date: new ISODate( "2013-08-05T15:24:25" ) } );
db.so.insert( { date: new ISODate( "2013-08-05T15:24:32" ) } );
db.so.insert( { date: new ISODate( "2013-08-05T15:24:45" ) } );
db.so.insert( { date: new ISODate( "2013-08-05T15:25:15" ) } );
db.so.insert( { date: new ISODate( "2013-08-05T15:25:15" ) } );

db.so.aggregate( [
    { $group: {
        _id: {
            y: { '$year': '$date' },
            m: { '$month': '$date' },
            d: { '$dayOfMonth': '$date' },
            h: { '$hour': '$date' },
            i: { '$minute': '$date' },
        },
        count: { $sum : 1 }
    } } 
] );

どの出力:

{
    "result" : [
        {
            "_id" : {
                "y" : 2013,
                "m" : 8,
                "d" : 5,
                "h" : 15,
                "i" : 25
            },
            "count" : 2
        },
        {
            "_id" : {
                "y" : 2013,
                "m" : 8,
                "d" : 5,
                "h" : 15,
                "i" : 24
            },
            "count" : 5
        }
    ],
    "ok" : 1
}
于 2013-08-05T15:31:43.647 に答える