Daten aggregieren

Die Google Health API bietet dedizierte Aggregationsendpunkte, die Gesundheitsdaten in Zeitfenstern gruppieren und zusammenfassen. Anstatt einzelne Rohdatensätze auf dem Client abzurufen und zu summieren, können Sie die Aggregationsendpunkte verwenden, um Messwerte (z. B. Summen, Durchschnittswerte, Mindest- und Höchstwerte) über einen abgeglichenen Datenstream zu berechnen:

  • Der rollUp-Endpunkt aggregiert Datenpunkte über physische Zeitintervalle in UTC mit einer konfigurierbaren Fensterdauer in Sekunden (windowSize).
  • Der Endpunkt dailyRollUp aggregiert Datenpunkte über einen oder mehrere Kalendertage (windowSizeDays) hinweg anhand der bürgerlichen Zeit relativ zur lokalen Uhr des Nutzers.

Beide Endpunkte gleichen automatisch sich überschneidende Datenpunkte auf verbundenen Geräten ab und schließen Zeiträume aus, in denen das Wearable nicht am Handgelenk getragen wurde, sofern der Datentyp die Trageerkennung unterstützt.

Aggregationsendpunkte vergleichen

Wählen Sie den Aggregationsendpunkt aus, der der Art und Weise entspricht, wie Ihre Anwendung Zeitreihen-Gesundheitsmesswerte gruppiert und anzeigt:

Funktion rollUp Endpunkt dailyRollUp Endpunkt
HTTP-Anfrage POST https://health.googleapis.com/v4/users/me/dataTypes/data-type/dataPoints:rollUp POST https://health.googleapis.com/v4/users/me/dataTypes/data-type/dataPoints:dailyRollUp
Zeitdarstellung Physische Zeit in UTC (startTime und endTime im RFC 3339-Format). Bürgerliche Zeit (start und end als CivilDateTime-Objekte).
Fensterparameter windowSize (erforderliche Stringdauer in Sekunden, mindestens "1s"). windowSizeDays (optional, Ganzzahl für die Anzahl der Tage, Standardwert ist 1).
Antwortobjekt RollupDataPoint DailyRollupDataPoint
Reihenfolge der Antworten Umgekehrt chronologische Reihenfolge (neuestes Fenster zuerst). Umgekehrt chronologische Reihenfolge (neuestes Fenster zuerst).
Optimal für Intraday-Diagramme, stündliche oder minütliche Histogramme und UTC-Analyse mit fester Dauer. Tägliche Dashboards, mehrtägige Trends und Zusammenfassungen, die Zeitzonenreisen oder die Sommerzeit berücksichtigen.

An beiden Endpunkten gelten maximale Abfragebereichslimits, die vom Datentyp abhängen:

  • Für calories-in-heart-rate-zone, heart-rate, active-minutes und total-calories gilt ein maximaler Abfragebereich von 14 Tagen.
  • Für alle anderen unterstützten Datentypen gilt ein maximaler Abfragezeitraum von 90 Tagen.

Welche Datentypen rollup und dailyRollup unterstützen, erfährst du in der Referenz zu den Datentypen der Google Health API.

Über physische Zeitintervalle aggregieren

Verwenden Sie den rollUp-Endpunkt, um Datenpunkte über eine physische Zeit range (in UTC) zu aggregieren, gruppiert nach einer Fensterdauer in Sekunden (windowSize).

Geben Sie beim Aufrufen des Endpunkts rollUp einen JSON-Anfragetext an, der das geschlossene/offene range (startTime einschließlich, endTime ausschließlich) und windowSize enthält. Beachten Sie die folgenden windowSize-Anforderungen:

  • Die Dauer von windowSize muss mindestens 1 Sekunde ("1s") betragen. Die API lehnt Dauern von weniger als einer Sekunde, null oder negative Dauern mit dem Fehler 400 Bad Request (INVALID_ROLLUP_WINDOW) ab.
  • Um eine ungleichmäßige Verteilung der aggregierten Daten auf die Unter-Buckets zu vermeiden, wählen Sie einen windowSize aus, der mindestens so groß ist wie die zugrunde liegende Speicherauflösung des Datentyps (z. B. "60s" für 1-Minuten-Schrittintervalle). Weitere Informationen finden Sie unter Roll-up-Fenster und Speicherauflösung.

Mit der folgenden Anfrage werden beispielsweise die Schrittzahlen in 1-Minuten-Intervallen (60s) zusammengefasst:

Anfrage

POST https://health.googleapis.com/v4/users/me/dataTypes/steps/dataPoints:rollUp
Authorization: Bearer access-token
Accept: application/json

{
  "range": {
    "startTime": "2026-02-17T17:00:00Z",
    "endTime": "2026-02-17T17:59:59Z"
  },
  "windowSize": "60s"
}

Antwort

{
  "rollupDataPoints": [
    {
      "startTime": "2026-02-17T17:55:00Z",
      "endTime": "2026-02-17T17:56:00Z",
      "steps": {
        "countSum": "72"
      }
    },
    {
      "startTime": "2026-02-17T17:54:00Z",
      "endTime": "2026-02-17T17:55:00Z",
      "steps": {
        "countSum": "85"
      }
    },
...
  ]
}

Über Kalendertage hinweg aggregieren

Verwende den dailyRollUp-Endpunkt, um Daten für einen einzelnen Kalendertag oder mehrere Tage (windowSizeDays) zu aggregieren. Gib die geschlossene/offene bürgerliche Zeit range (start und end) im Anfragetext an. Je nach Datentyp gibt der Endpunkt aggregierte Werte wie die Summe oder den Durchschnitt für jedes Zeitfenster zurück.

Da dailyRollUp die bürgerliche Zeit verwendet und die UTC-Abweichungen berücksichtigt, die mit jedem Datenpunkt aufgezeichnet werden, werden variable Tageslängen, die durch die Umstellung auf Sommerzeit oder Reisen durch Zeitzonen verursacht werden, automatisch ausgeglichen.

In der folgenden Anfrage werden beispielsweise die Schrittzahlen für einen einzelnen Kalendertag (windowSizeDays: 1) aggregiert:

Anfrage

POST https://health.googleapis.com/v4/users/me/dataTypes/steps/dataPoints:dailyRollUp
Authorization: Bearer access-token
Accept: application/json

{
  "range": {
    "start": {
      "date": {
        "year": 2026,
        "month": 2,
        "day": 26
      },
      "time": {
        "hours": 0,
        "minutes": 0,
        "seconds": 0,
        "nanos": 0
      }
    },
    "end": {
      "date": {
        "year": 2026,
        "month": 2,
        "day": 26
      },
      "time": {
        "hours": 23,
        "minutes": 59,
        "seconds": 59,
        "nanos": 0
      }
    }
  },
  "windowSizeDays": 1
}

Antwort

{
  "rollupDataPoints": [
    {
      "civilStartTime": {
        "date": {
          "year": 2026,
          "month": 2,
          "day": 26
        },
        "time": {}
      },
      "civilEndTime": {
        "date": {
          "year": 2026,
          "month": 2,
          "day": 26
        },
        "time": {
          "hours": 23,
          "minutes": 59,
          "seconds": 59
        }
      },
      "steps": {
        "countSum": "3822"
      }
    }
  ]
}

Nach Datenquellenfamilie aggregieren

Sowohl rollUp als auch dailyRollUp akzeptieren ein optionales dataSourceFamily-Feld im JSON-Anfragetext, um die Aggregation auf bestimmte Quellgruppen zu beschränken:

  • Mit der Option users/me/dataSourceFamilies/all-sources (Standard) werden Daten aggregiert, die über alle registrierten selbst erhobenen und Drittanbieterquellen hinweg abgeglichen wurden.
  • Mit der Option users/me/dataSourceFamilies/google-wearables werden Daten aggregiert, die von Google- und Fitbit-Wearables aufgezeichnet wurden. Manuell protokollierte und vom Smartphone geschätzte Daten sind davon ausgeschlossen.
  • Mit der Option users/me/dataSourceFamilies/google-sources werden Daten aus Google- und Fitbit-Quellen aggregiert, einschließlich Wearable-Trackern, Health Connect und manuellen Einträgen in Erstanbieter-Apps.

Vollständige Parameteranforderungen sowie Anfrage- und Antwortbeispiele finden Sie im Leitfaden zum Filtern von Daten unter Nach Datenquellenfamilie filtern.

Roll-up-Fenster und Speicherauflösung

Der Endpunkt rollUp akzeptiert zwar jede windowSize von 1 Sekunde ("1s") oder mehr, aber verschiedene Datentypen zeichnen Messwerte mit unterschiedlichen Abtastraten oder Intervalldauern im zugrunde liegenden Speicher auf und speichern sie. Beispielsweise werden Messwerte zur körperlichen Aktivität von Wearables wie steps, distance, active-minutes und active-energy-burned in der Regel in Intervallen von 1 Minute (60s) aufgezeichnet.

In der folgenden Tabelle sind die zugrunde liegenden Speicherauflösungen und die empfohlenen Mindestwerte für windowSize für gängige Datentypen aufgeführt:

Speicherauflösung Empfohlene Mindestanforderungen: windowSize Datentypen
1 Sekunde (1s) "1s" heart-rate
1 Minute (60s) "60s" active-energy-burned, active-minutes, active-zone-minutes, altitude, calories-in-heart-rate-zone, distance, floors, steps, time-in-heart-rate-zone, total-calories

Beim Aggregieren von Intervalldatentypen platziert der Endpunkt rollUp jeden aufgezeichneten Datenpunkt in den Bucket, der den startTime des Datenpunkts enthält. Die API schneidet, interpoliert oder verteilt Intervalldaten nicht auf Unterintervall-Buckets.

Wenn Sie ein windowSize angeben, das kleiner als das zugrunde liegende Datenspeicherintervall ist (z. B. ein 10-Sekunden-Fenster für steps, das in 1-Minuten-Intervallen gespeichert wird):

  1. Der erste Unter-Bucket, der mit dem startTime des Intervalls übereinstimmt (z. B. 10:00:00 bis 10:00:10), erhält die kumulierte Anzahl der gesamten Minute (z. B. alle 100 Schritte, die für diese Minute aufgezeichnet wurden).
  2. Die verbleibenden Unter-Buckets innerhalb derselben Minute (10:00:10 bis 10:00:20, 10:00:20 bis 10:00:30 usw.) erhalten keine Datenpunkte, da innerhalb dieser Zeitfenster kein Intervall beginnt.

Dies führt zu Daten mit Spitzen, bei denen der Wert des gesamten Intervalls im ersten Unterfenster konzentriert ist, wie in Abbildung 1 dargestellt.

Roll-up-Bucketing für Unterintervalle im Vergleich zur Speicherauflösung
Abbildung 1: Bucketing für die Zusammenfassung von Unterintervallen, bei dem ein 1-minütiges Intervall dem ersten 10-sekündigen Unter-Bucket nach startTime zugewiesen wird

Um gleichmäßig verteilte und aussagekräftige Zusammenfassungen zu erhalten, legen Sie für windowSize immer eine Dauer fest, die mindestens der zugrunde liegenden Speicherauflösung des Zieldatentyps entspricht (z. B. "60s" oder größer für steps). Informationen zur Speicherauflösung und zum empfohlenen Mindest-Rollup-Fenster für jeden Datentyp finden Sie in der Referenz zu den Google Health API-Datentypen.

Bucketing, wenn der Bereich kein Vielfaches der Fenstergröße ist

Wenn der angeforderte Bereich kein genaues Vielfaches von windowSize (oder windowSizeDays) ist, wird der letzte chronologische Bucket am oberen Endpunkt des Bereichs abgeschnitten und deckt eine Dauer ab, die kürzer als die Fenstergröße ist. Die API akzeptiert Ihre Anfrage ohne Änderungen und führt keine Rundungen, Zeitverschiebungen oder Dateninterpolationen durch.

Um den gesamten angeforderten Bereich abzudecken, verwendet die API die Aufrundungsdivision, um die Gesamtzahl der Aggregationsfenster zu berechnen:

Number of windows = ceiling(Range duration / Window size)

Jeder Bucket beginnt sequenziell am Anfang des Bereichs. Wenn das Hinzufügen eines weiteren Fensters in voller Größe über die angeforderte Endzeit hinausgeht, wird das letzte Fenster am Ende des Bereichs abgeschnitten (begrenzt).

Funktionsweise der Bucket-Erstellung

Wenn Sie Roll-ups mit nicht teilbaren Bereichen anfordern, wendet die API die folgenden Regeln an:

  • Die Bucket-Erstellung beginnt am Anfang des angeforderten Bereichs (range.startTime oder range.start) und wird um die Fenstergröße (windowSize oder windowSizeDays) fortgesetzt.
  • Der letzte chronologische Bucket wird am Ende des angeforderten Bereichs (range.endTime oder range.end) abgeschnitten und deckt eine kürzere Dauer als die angeforderte Fenstergröße ab.
  • Die zurückgegebenen RollupDataPoint- oder DailyRollupDataPoint-Objekte enthalten eigene explizite Start- und Endzeitstempel, mit denen Sie die tatsächliche Dauer des gekürzten Buckets prüfen können.
  • Da die API Roll-up-Daten in umgekehrter chronologischer Reihenfolge (neueste zuerst) zurückgibt, wird der letzte chronologische Bucket (der abgeschnittene Bucket) als erstes Element (index 0) in der zurückgegebenen Liste angezeigt.

Abbildung 2 zeigt, wie die API einen nicht teilbaren Bereich ab range.startTime in Buckets aufteilt, den letzten Bucket bei range.endTime begrenzt und die resultierenden Buckets in umgekehrter chronologischer Reihenfolge zurückgibt.

Rollup-Bucketing, Kürzung und Antwortreihenfolge
Abbildung 2: Rollup-Bucketing, Kürzung am Ende des Bereichs und umgekehrt chronologische Reihenfolge der Antworten

Beispiel für einen 12-minütigen Bereich mit einem 5-minütigen Fenster

Angenommen, ein Client fordert einen Roll-up über einen Zeitraum von 12 Minuten mit einem windowSize ("300s") von 5 Minuten an:

  • Der Wert für range.startTime ist 10:00:00Z.
  • Der Wert für range.endTime ist 10:12:00Z, was einer Gesamtdauer von 12 Minuten entspricht.
  • Der Wert für windowSize ist "300s" (5 Minuten).

Da 12 Minuten kein genaues Vielfaches von 5 Minuten (12 = 5 * 2 + 2) sind, berechnet die API die Anzahl der Fenster als ceiling(12 / 5) = 3. Dadurch entstehen drei chronologische Buckets:

Bucket Intervall Dauer Status des Zeitraums
Bucket 1 [10:00:00Z, 10:05:00Z) 5 Minuten Vollbildmodus
Bucket 2 [10:05:00Z, 10:10:00Z) 5 Minuten Vollbildmodus
Bucket 3 [10:10:00Z, 10:12:00Z) 2 Minuten Abgeschnitten bei range.endTime

Auswirkungen auf aggregierte Werte

Da das letzte chronologische Zeitfenster kürzer ist, sind additive Messwerte (z. B. die Summe oder Anzahl der Schritte) im gekürzten Bucket aufgrund der kürzeren Zeitspanne niedriger.

Wenn ein Nutzer während dieses gesamten 12-minütigen Zeitraums mit einer konstanten Geschwindigkeit von 100 Schritten pro Minute geht, enthalten die Buckets die folgenden Gesamtzahlen:

  • In Bucket 1 (10:00:00Z bis 10:05:00Z) werden 500 Schritte aufgezeichnet (5 Minuten bei 100 Schritten pro Minute).
  • In Bucket 2 (10:05:00Z bis 10:10:00Z) werden 500 Schritte aufgezeichnet (5 Minuten bei 100 Schritten pro Minute).
  • In Bucket 3 (10:10:00Z bis 10:12:00Z) werden 200 Schritte aufgezeichnet (2 Minuten mit 100 Schritten pro Minute).

Die niedrigere Schrittzahl von 200 Schritten in Bucket 3 ist auf die 2-minütige Dauer des verkürzten Zeitfensters zurückzuführen, nicht auf einen Rückgang der Aktivität des Nutzers. Wenn Sie diese Daten grafisch darstellen oder analysieren, sollten Sie die Anzahl mithilfe der expliziten Dauer jedes Buckets normalisieren, um einen irreführenden Rückgang der Nutzeraktivität zu vermeiden.

In Abbildung 3 werden die Rohdaten der additiven Schrittsummen (countSum) mit den nach Dauer normalisierten Raten in den drei Gruppen verglichen.

Vergleich der Gesamtzahl der Schritte in Rohdaten-Buckets und der normalisierten Schrittraten
Abbildung 3: Rohdaten im Vergleich zu den nach Dauer normalisierten Raten für einen gekürzten Rollup-Bucket

Beispiel für eine API-Antwort mit Sortierung

Da die API Ergebnisse in umgekehrter chronologischer Reihenfolge zurückgibt, wird der abgeschnittene Bucket als erstes Element in der zurückgegebenen Liste angezeigt:

{
  "rollupDataPoints": [
    {
      "startTime": "2026-08-20T10:10:00Z",
      "endTime": "2026-08-20T10:12:00Z",
      "steps": {
        "countSum": "200"
      }
    },
    {
      "startTime": "2026-08-20T10:05:00Z",
      "endTime": "2026-08-20T10:10:00Z",
      "steps": {
        "countSum": "500"
      }
    },
    {
      "startTime": "2026-08-20T10:00:00Z",
      "endTime": "2026-08-20T10:05:00Z",
      "steps": {
        "countSum": "500"
      }
    }
  ]
}