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".