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

ドキュメント内のキーが平均集計を変化させる複数のフィールド

    コンセプトの概要

    非常に短いコメントで基本的に言っていたのは、代わりに センサーの「キー」名ごとに個別の集計クエリを発行する場合は、 ONEに入力できます。 、「平均」を正しく計算する限り。

    もちろん、データの問題は、「キー」がすべてのドキュメントに存在するわけではないということです。したがって、正しい「平均」を取得するには、$avg キーが存在するかどうかに関係なく、「すべての」ドキュメントがカウントされるためです。

    したがって、代わりに「数学」を分割し、$group 合計Count 合計Sum 最初に各キーの。これは、 $ifNullを使用します フィールドの存在をテストし、 $cond 返す値を変更します。

    .aggregate([
      { "$match": {
        "$or": [
          { "Technique-Electrique_VMC Aldes_Power4[W]": { "$exists": True } },
          { "Technique-Electrique_VMC Unelvent_Power5[W]": { "$exists": True } }
        ]
      }}
      { "$group":{
        "_id":{
          "year":{ "$year":"$timestamp" },
          "month":{ "$month":"$timestamp" }
        },
        "Technique-Electrique_VMC Aldes_Power4[W]-Sum": { 
          "$sum": { 
            "$ifNull": [ "$Technique-Electrique_VMC Aldes_Power4[W]", 0 ]
          }
        },
        "Technique-Electrique_VMC Aldes_Power4[W]-Count": { 
          "$sum": { 
            "$cond": [
              { "$ifNull": [ "$Technique-Electrique_VMC Aldes_Power4[W]", false ] },
              1,
              0
            ]
          }
        },
        "Technique-Electrique_VMC Unelvent_Power5[W]-Sum": {
          "$sum": { 
            "$ifNull": [ "$Technique-Electrique_VMC Unelvent_Power5[W]", 0 ]
          }
        },
        "Technique-Electrique_VMC Unelvent_Power5[W]-Count": {
          "$sum": {
            "$cond": [ 
              { "$ifNull": [ "$Technique-Electrique_VMC Unelvent_Power5[W]", false ] },
              1,
              0
            ]
          }
        }
      }},
      { "$project": {
        "Technique-Electrique_VMC Aldes_Power4[W]-Avg": {
          "$divide": [
            "$Technique-Electrique_VMC Aldes_Power4[W]-Sum",
            "$Technique-Electrique_VMC Aldes_Power4[W]-Count"
          ]
        },
        "Technique-Electrique_VMC Unelvent_Power5[W]-Avg": {
          "$divide": [
            "Technique-Electrique_VMC Unelvent_Power5[W]-Sum",
            "Technique-Electrique_VMC Unelvent_Power5[W]-Count"
          ]
        }
      }}
    ])
    

    $cond 演算子は「三項」演算子です。これは、最初の「if」条件がtrueであることを意味します。 、"then" 2番目の引数が返され、"else"3番目の引数が返されます。

    したがって、"Count"の3項のポイント 解決することです:

    • フィールドが存在する場合は、カウントに1を返します
    • それ以外の場合は、存在しない場合は0を返します

    $groupの後 Averageを取得するために行われます $divideを使用します 別々の $project ステージ。

    最終結果は、提供するすべてのキーの「平均」であり、これは、フィールドが実際に存在するドキュメントの値とカウントを追加することのみを考慮したものです。

    したがって、すべてのキーを1つの集計ステートメントに入れると、処理にかかる時間とリソースを大幅に節約できます。

    パイプラインの動的生成

    したがって、Pythonでこれを「動的に」行うには、リストから始めます。

    sensors = ["Technique-Electrique_VMC Aldes_Power4[W]", "Technique-Electrique_VMC Unelvent_Power5[W]"]
    
    match = { '$match': { '$or': map(lambda x: { x: { '$exists': True } },sensors) } }
    
    group = { '$group': { 
      '_id': {
        'year': { '$year': '$timestamp' },
        'month': { '$month':'$timestamp' }
      }
    }}
    
    project = { '$project': {  } }
    
    for k in sensors:
      group['$group'][k + '-Sum'] = {
        '$sum': { '$ifNull': [ '$' + k, 0 ] }
      }
      group['$group'][k + '-Count'] = {
        '$sum': { '$cond': [ { '$ifNull': [ '$' + k, False ] }, 1, 0 ]  }
      }
      project['$project'][k + '-Avg'] = {
        '$divide': [ '$' + k + '-Sum', '$' + k + '-Count' ]
      }
    
    pipeline = [match,group,project]
    

    これは、「センサー」の特定のリストについて、上記の完全なリストと同じものを生成します。




    1. MongoDBは、存在するエントリのみで並べ替え、最初に値を持つキー、最後にnullまたは存在しないキーを持つキー

    2. MongoDBクライアントのタイムアウトオプションについて

    3. C#MongoDB個別クエリ構文

    4. 大文字と小文字を区別せずにmongoでユーザー名にインデックスを付ける方法は?