sql >> データベース >  >> NoSQL >> MongoDB

時間間隔内のMongo集約

    どの出力形式がニーズに最も適しているかに応じて、これにアプローチする方法がいくつかあります。主な注意点は、「集約フレームワーク」> それ自体、実際には「キャスト」を日付として返すことはできませんが、 Dateに簡単に再構築できる値を取得できます。 APIで結果を処理するときのオブジェクト。

    最初のアプローチは、 "Date AggregationOperators" を使用することです。 集約フレームワークで利用可能:

    db.collection.aggregate([
        { "$match": {
            "time": { "$gte": startDate, "$lt": endDate }
        }},
        { "$group": {
            "_id": {
                "year": { "$year": "$time" },
                "dayOfYear": { "$dayOfYear": "$time" },
                "hour": { "$hour": "$time" },
                "minute": {
                    "$subtract": [
                        { "$minute": "$time" },
                        { "$mod": [ { "$minute": "$time" }, 10 ] }
                    ]
                }
            },
            "count": { "$sum": 1 }
        }}
    ])
    

    _idの複合キーを返します 「日付」に必要なすべての値が含まれています。または、常に「1時間」以内の場合は、「分」の部分を使用して、 startDateに基づいて実際の日付を計算します。 範囲の選択。

    または、単純な「日付計算」を使用して、「エポック」からのミリ秒を取得することもできます。これも、日付コンストラクターに直接フィードできます。

    db.collection.aggregate([
        { "$match": {
            "time": { "$gte": startDate, "$lt": endDate }
        }},
        { "$group": {
            "_id": {
                "$subtract": [
                   { "$subtract": [ "$time", new Date(0) ] },
                   { "$mod": [
                       { "$subtract": [ "$time", new Date(0) ] },
                       1000 * 60 * 10
                   ]}
                ]
            },
            "count": { "$sum": 1 }
        }}
    ])
    

    すべての場合において、しないこと やりたいのは、 $ project> 実際に適用する前に $ group 。 「パイプラインステージ」として、 $ project 選択したすべてのドキュメントを「循環」させ、コンテンツを「変換」する必要があります。

    これには時間かかります 、クエリの実行合計に追加します。 $ groupに申し込むだけです。 示されているように直接。

    または、 Dateについて本当に「純粋」な場合 オブジェクトが後処理なしで返される場合は、いつでも"mapReduce"> 、JavaScript関数は実際には日付としての再キャストを許可しますが、集計フレームワークよりも遅く、もちろんカーソル応答がないためです:

    db.collection.mapReduce(
       function() {
           var date = new Date(
               this.time.valueOf() 
               - ( this.time.valueOf() % ( 1000 * 60 * 10 ) )
           );
           emit(date,1);
       },
       function(key,values) {
           return Array.sum(values);
       },
       { "out": { "inline": 1 } }
    )
    

    ただし、応答の変換は非常に簡単であるため、最善の策は集計を使用することです。

    db.collection.aggregate([
        { "$match": {
            "time": { "$gte": startDate, "$lt": endDate }
        }},
        { "$group": {
            "_id": {
                "year": { "$year": "$time" },
                "dayOfYear": { "$dayOfYear": "$time" },
                "hour": { "$hour": "$time" },
                "minute": {
                    "$subtract": [
                        { "$minute": "$time" },
                        { "$mod": [ { "$minute": "$time" }, 10 ] }
                    ]
                }
            },
            "count": { "$sum": 1 }
        }}
    ]).forEach(function(doc) {
        doc._id = new Date(doc._id);
        printjson(doc);
    })
    

    次に、実際の Dateを使用した間隔グループ化の出力があります。 オブジェクト。



    1. spring-data2.0.xでRedisCacheManagerを作成する方法

    2. 非同期nodejsのクエリと処理結果

    3. MongoDBJava3.0ドライバーを使用した一括アップサート

    4. スキーマを埋め込むとエラーが発生します