sql >> Database teknologi >  >> NoSQL >> MongoDB

Flere felter, hvor nøgler i dokument varierer Gennemsnitlig aggregation

Konceptoversigt

Hvad jeg dybest set sagde i den meget korte kommentar er, at i stedet for at udstede en separat aggregeringsforespørgsel for hvert sensor "nøgle" navn, kan du indsætte det i ONE , så længe du beregner "gennemsnittene" korrekt.

Selvfølgelig er problemet i dine data, at "nøglerne" ikke er til stede i alle dokumenter. Så for at få det korrekte "gennemsnit", kan vi ikke bare bruge $avg da det ville tælle "ALLE" dokumenter, uanset om nøglen var til stede eller ej.

Så i stedet opdeler vi "matematikken" og laver en $group for det samlede Count og samlet Sum af hver nøgle først. Dette bruger $ifNull at teste for tilstedeværelsen af ​​feltet, og også $cond for at skifte værdier for at returnere.

.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 operator er en "ternær" operator, hvilket betyder, hvor den første "hvis"-betingelse er true , "så" returneres det andet argument, "ellers" returneres det tredje argument.

Altså punktet for det ternære i "Count" er at træne:

  • Hvis feltet er der, så returner 1 for optælling
  • Ellers returnerer 0, når det ikke er der

Efter $group er gjort, for at få Average vi bruger $divide på de to numre, der er produceret for hver nøgle i et separat $project scene.

Slutresultatet er "gennemsnittet" for hver nøgle, du leverer, og dette overvejede kun at tilføje værdier og tæller for dokumenter, hvor feltet faktisk var til stede.

Så ved at lægge alle nøglerne i den ene sammenlægningserklæring vil du spare en masse tid og ressourcer på behandlingen.

Dynamisk generering af rørledning

Så for at gøre dette "dynamisk" i python, start med listen:

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]

Hvilket genererer det samme som den fulde liste ovenfor for en given liste over "sensorer".




  1. Opdater array-element efter id med mongo-forespørgsel

  2. Ændring af Redis-port i Docker Compose virker ikke

  3. MongoDB Replica Set:Diskstørrelsesforskel i primære og sekundære noder

  4. Meteor klient side sortering Samling