MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Wiele pól, w których klucze w dokumencie różnią się od średniej agregacji

Zarys koncepcji

Zasadniczo powiedziałem w bardzo krótkim komentarzu, że zamiast do wydawania oddzielnego zapytania agregującego dla każdej nazwy „klucza” czujnika, możesz umieścić je w JEDEN , o ile poprawnie obliczysz „średnie”.

Oczywiście problem w Twoich danych polega na tym, że „klucze” nie występują we wszystkich dokumentach. Aby uzyskać prawidłową „średnią”, nie możemy po prostu użyć $avg ponieważ policzyłoby "WSZYSTKIE" dokumenty, niezależnie od tego, czy klucz był obecny, czy nie.

Więc zamiast tego dzielimy „matematykę” i wykonujemy $group dla całkowitej Count i całkowita Sum najpierw każdego klucza. Używa $ifNull aby przetestować obecność pola, a także $cond do wartości alternatywnych do zwrócenia.

.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 jest operatorem „trójargumentowym”, co oznacza, że ​​pierwszy warunek „if” ma wartość true , "wtedy" zwracany jest drugi argument, "inaczej" zwracany jest trzeci argument.

Więc punkt trójki w "Count" jest ćwiczenie:

  • Jeśli pole tam jest, zwróć 1 dla licznika
  • W przeciwnym razie zwróć 0, gdy go tam nie ma

Po $group jest zrobione, aby uzyskać Average używamy $divide na dwóch liczbach wygenerowanych dla każdego klucza w osobnym $project scena.

Wynikiem końcowym jest „średnia” dla każdego podanego klucza, a to uwzględniało tylko dodawanie wartości i liczby dla dokumentów, w których pole faktycznie było obecne.

Dzięki temu umieszczenie wszystkich kluczy w jednej instrukcji agregacji zaoszczędzi wiele czasu i zasobów związanych z przetwarzaniem.

Dynamiczne generowanie potoku

Aby zrobić to „dynamicznie” w Pythonie, zacznij od listy:

Czujniki
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]

Co generuje to samo, co pełna lista powyżej dla danej listy „czujników”.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Wysyłanie JSON do Flask powoduje błąd 400 Bad Request

  2. Jak pobrać / znaleźć wszystkie elementy tablicy zagnieżdżonej w MongoDB Java

  3. Jak uzyskać wiele obiektów JSON przy użyciu nodejs i mangusty?

  4. Symbol wieloznaczny MongoDB w kluczu zapytania

  5. Dopasuj wiele kryteriów w tablicy