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

日ごと、時間ごとのMongodb集計

    基本的に必要なのは二重グループ化ですが、日付集計演算子 、関連する部分のみ:

    db.collection.aggregate([
        { "$group": {
            "_id": {
                "customerId": "$customerId",
                "day": { "$dayOfYear": "$startTime" },
                "hour": { "$hour": "$startTime" }
            },
            "pings": { "$sum": "$ping" },
            "links": { "$sum": "$link" }
        }},
        { "$group": {
           "_id": {
               "customerId": "$_id.customerId",
               "day": "$_id.day"
           },
           "hours": { 
               "$push": { 
                   "hour": "$_id.hour",
                   "pings": "$pings",
                   "links": "$links"
               }
           }
        }}
    ])
    

    ダブル $group 結果を1日あたりの配列に配置することにより、必要な形式を提供します。サンプルには単一のドキュメントが含まれていますが、基本的に次のような結果が得られます。

    {
        "_id" : {
                "customerId" : 123,
                "day" : 365
        },
        "hours" : [
                {
                        "hour" : 10,
                        "pings" : 2,
                        "links" : 3
                }
        ]
    }
    

    日付演算子の結果を処理するのが難しい場合、または日付オブジェクトの単純化された「パススルー」結果が必要な場合は、代わりにエポックタイムスタンプとしてキャストできます。

    db.collection.aggregate([
        { "$group": {
            "_id": {
                "customerId": "$customerId",
                "day": {
                   "$subtract": [
                       { "$subtract": [ "$startTime", new Date("1970-01-01") ] },
                       {
                           "$mod": [
                               { "$subtract": [ "$startTime", new Date("1970-01-01") ] },
                               1000*60*60*24   
                           ]
                       }
                   ]
                },
                "hour": {
                   "$subtract": [
                       { "$subtract": [ "$startTime", new Date("1970-01-01") ] },
                       {
                           "$mod": [
                               { "$subtract": [ "$startTime", new Date("1970-01-01") ] },
                               1000*60*60   
                           ]
                       }
                   ]
                }
            },
            "pings": { "$sum": "$ping" },
            "links": { "$sum": "$link" }
        }},
        { "$group": {
           "_id": {
               "customerId": "$_id.customerId",
               "day": "$_id.day"
           },
           "hours": { 
               "$push": { 
                   "hour": "$_id.hour",
                   "pings": "$pings",
                   "links": "$links"
               }
           }
        }}
    ])
    

    そこにある秘訣は、 $subtract ある日付オブジェクトから別の日付オブジェクトを取得すると、結果として「エポック」値が返されます。この場合、「エポック」開始日を使用してタイムスタンプ値全体を取得し、「日付計算」を提供して時間を必要な間隔に修正します。したがって、結果:

    {
        "_id" : {
                "customerId" : 123,
                "day" : NumberLong("1419984000000")
        },
        "hours" : [
                {
                        "hour" : NumberLong("1420020000000"),
                        "pings" : 2,
                        "links" : 3
                }
        ]
    }
    

    ニーズに応じて、結果として日付演算子が提供するものよりも、どちらが口に合うかもしれません。

    $let スコープ操作の「変数」を宣言できる演算子:

    db.event.aggregate([
        { "$group": {
            "_id": {
                "$let": {
                    "vars": { 
                       "date": { "$subtract": [ "$startTime", new Date("1970-01-01") ] },
                       "day": 1000*60*60*24,
                       "hour": 1000*60*60
                    },
                    "in": {
                        "customerId": "$customerId",
                        "day": {
                            "$subtract": [
                                "$$date",
                                { "$mod": [ "$$date", "$$day" ] }
                             ]
                        },
                        "hour": {
                            "$subtract": [
                                "$$date",
                                { "$mod": [ "$$date", "$$hour" ] }
                             ]
                        }
                    }
                }
            },
            "pings": { "$sum": "$ping" },
            "links": { "$sum": "$link" }
        }},
        { "$group": {
           "_id": {
               "customerId": "$_id.customerId",
               "day": "$_id.day"
           },
           "hours": { 
               "$push": { 
                   "hour": "$_id.hour",
                   "pings": "$pings",
                   "links": "$links"
               }
           }
        }}
    ])
    

    また、「ping」と「link」の値は、タイプミスでない限り、実際には文字列であることに言及するのをほとんど忘れていました。ただし、そうでない場合は、最初に数値として変換してください。




    1. mongodb c#特定のフィールドドット表記を選択

    2. ノードサーバーを再起動しない限り、mongodbの更新が表示されない

    3. MongoError:UNKNOWNに接続します

    4. Nodejsのクライアントエラーに送信された後、ヘッダーを設定できないのはなぜですか?