2016-06-02 9 views
0

私は、コレクションの次のような内容の集約を作成する困難を抱えている:のMongoDB:集計配列

{ 
    "_id": ObjectId("574ffe9bda461e4b4b0043ab"), 
    "hostname": "baklap4", 
    "timestamp": NumberLong(1464860311), 
    "networkList": [ 
    { 
     "name": "wlp5s0", 
     "receive": NumberLong(53845), 
     "transmit": NumberLong(20999) 
    }, 
    { 
     "name": "enp6s0", 
     "receive": NumberLong(0), 
     "transmit": NumberLong(0) 
    } 
    ] 
} 

ここでの問題Networklistは、デバイスの名前と、どのくらいのデータ持たを保持する配列されています出入りしました。

私が持っているもの: 一意の名前に基づいて、平均でreceivetransmitが欲しいです。

それ以外は、平均は300秒で分割されたすべてのドキュメントに適用されます(これはtimestampフィールドを使用しています)。今まで

私のクエリは次のようになります。

db.NetworkInfo.aggregate([ 
    { "$unwind": "$networkList" }, 
    { "$group": 
     { "_id": 
      { "interval": 
       { "$subtract": [ "$timestamp", { "$mod": [ "$timestamp", 60 * 5 ] } ] } 
      }, 
     "receive": { "$avg": "$networkList.receive" }, 
     "transmit": { "$avg": "$networkList.transmit" }, 
     "timestamp": { "$max": "$timestamp" } 
     } 
    }, 
    { "$project": 
     { "_id": 0, 
      "receive": 1, 
      "transmit": 1, 
      "timestamp": 1 
     } 
    }, 
    {$sort: {"timestamp": -1}} 
]) 

このクエリは、文書のすべてを通過し、300秒で分割されたグループでそれらを分割します。 次に、受信データと送信データの平均を計算します。 しかし、ネットワークリストに2つのエントリがあるので、この場合の平均値は(53845+0)/2

です。これは私が望むものではありません。私はすべてのドキュメントのために、receivetransmitをそれぞれのデバイスだけで平均化したいと思います。

どうすればよいですか?

答えて

0

私はグループに別のキーを追加することでこれを修正しました。その結果、文書をある間隔で分割し、異なる装置名に分割することができました。これは私の集計です:

$aggregation = [ 
       [ 
        '$match' => [ 
         'timestamp' => ['$gte' => $todayMidnight], 
         'hostname' => $serverName 
        ] 
       ], 
       [ 
        '$unwind' => '$networkList' 
       ], 
       [ 
        '$group' => [ 
         '_id' => [ 
          'interval' => [ 
           '$subtract' => [ 
            '$timestamp', 
            [ 
             '$mod' => ['$timestamp', 300] 
            ] 
           ] 
          ], 
          'name' => '$networkList.name' 
         ], 
         'name' => [ 
          '$last' => '$networkList.name' 
         ], 
         'receive' => [ 
          '$avg' => '$networkList.receive' 
         ], 
         'transmit' => [ 
          '$avg' => '$networkList.transmit' 
         ], 
         'timestamp' => [ 
          '$max' => '$timestamp' 
         ] 
        ] 
       ], 
       [ 
        '$project' => [ 
         '_id' => 0, 
         'receive' => 1, 
         'transmit' => 1, 
         'name' => 1, 
         'timestamp' => 1 
        ] 
       ], 
       [ 
        '$sort' => [ 
         'timestamp' => -1 
        ] 
       ] 
      ];