Google Health API предоставляет выделенные конечные точки агрегирования, которые группируют и обобщают информацию о здоровье по временным окнам. Вместо того чтобы получать и суммировать отдельные необработанные записи на клиенте, используйте конечные точки агрегирования для вычисления показателей (таких как итоги, средние, минимальные и максимальные значения) по согласованному потоку данных:
- Конечная точка
rollUpагрегирует элементы данных за физические интервалы времени в формате UTC, используя настраиваемую продолжительность окна в секундах (windowSize). - Конечная точка
dailyRollUpагрегирует элементы за один или несколько календарных дней (windowSizeDays), используя гражданское время относительно местных часов пользователя.
Обе конечные точки автоматически сопоставляют перекрывающиеся элементы данных на подключенных устройствах и исключают периоды, когда носимое устройство не было надето на запястье (для типов данных, поддерживающих определение нахождения на запястье).
Сравнение конечных точек агрегирования
Выберите конечную точку агрегирования, которая соответствует тому, как ваше приложение группирует и отображает временные ряды показателей здоровья:
| Функция | rollUp конечная точка |
dailyRollUp конечная точка |
|---|---|---|
| HTTP-запрос | 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 |
| Представление времени | Физическое время в формате UTC (startTime и endTime в формате RFC 3339). |
Гражданское время (start и end как объекты CivilDateTime). |
| Параметр окна | windowSize (обязательная строка, продолжительность в секундах, минимум "1s"). |
windowSizeDays (необязательное целое число дней, по умолчанию 1). |
| Объект ответа | RollupDataPoint |
DailyRollupDataPoint |
| Сортировка ответов | В обратном хронологическом порядке (сначала самое новое окно). | Обратный хронологический порядок (сначала самое новое окно). |
| Поддерживаемые устройства | Внутридневные диаграммы, гистограммы с почасовой или поминутной детализацией и анализ фиксированной продолжительности по UTC. | Ежедневные сводки, тренды за несколько дней и сводки, учитывающие смену часовых поясов или переход на летнее время. |
Для обеих конечных точек действуют ограничения на максимальный диапазон запроса в зависимости от типа данных:
- Для
calories-in-heart-rate-zone,heart-rate,active-minutesиtotal-caloriesмаксимальный диапазон дат составляет 14 дней. - Для всех остальных поддерживаемых типов данных максимальный диапазон запроса составляет 90 дней.
Чтобы узнать, какие типы данных поддерживают rollup и dailyRollup, ознакомьтесь со справочной статьей Типы данных Google Health API.
Агрегирование по физическим временным интервалам
Используйте конечную точку rollUp, чтобы агрегировать элементы данных за физическое время range (в формате UTC), сгруппированные по длительности окна в секундах (windowSize).
При вызове конечной точки rollUp укажите тело запроса JSON, содержащее полуоткрытый интервал range (включая startTime, исключая endTime) и windowSize. Учитывайте следующие требования к windowSize:
- Продолжительность
windowSizeдолжна быть не менее 1 секунды ("1s"). API отклоняет значения меньше секунды, нулевые и отрицательные значения, возвращая ошибку400 Bad Request(INVALID_ROLLUP_WINDOW). - Чтобы избежать неравномерного распределения агрегированных данных по подсегментам, выберите значение
windowSize, которое равно разрешению базового хранилища для типа данных или превышает его (например,"60s"для минутных интервалов шагов). Подробнее об окне свертки и разрешении хранилища…
Например, следующий запрос объединяет количество шагов за 1-минутные интервалы (60s):
Запрос
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"
}Ответ
{
"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"
}
},
...
]
}Агрегирование по календарным дням
Используйте конечную точку dailyRollUp, чтобы агрегировать данные за один или несколько календарных дней (windowSizeDays). Укажите в теле запроса полуинтервал гражданского времени range (start и end). В зависимости от типа данных конечная точка возвращает агрегированные значения, такие как сумма или среднее значение за каждый гражданский период.
Поскольку dailyRollUp работает по гражданскому времени, используя смещения UTC, записанные с каждым элементом данных, он автоматически согласовывает переменную продолжительность дня, вызванную переходом на летнее время или путешествием по часовым поясам.
Например, следующий запрос агрегирует количество шагов за один календарный день (windowSizeDays: 1):
Запрос
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
}Ответ
{
"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"
}
}
]
}Агрегировать по семейству источников данных
И rollUp, и dailyRollUp принимают необязательное поле dataSourceFamily в теле запроса JSON, чтобы ограничить агрегирование определенными группами источников:
- Вариант
users/me/dataSourceFamilies/all-sources(по умолчанию) позволяет агрегировать данные, сопоставленные по всем зарегистрированным собственным и сторонним источникам. - Вариант
users/me/dataSourceFamilies/google-wearablesагрегирует данные, записанные носимыми трекерами Google и Fitbit, за исключением данных, записанных вручную и рассчитанных телефоном. - Вариант
users/me/dataSourceFamilies/google-sourcesагрегирует данные из собственных источников Google и Fitbit, включая носимые трекеры, сервис "Здоровье и спорт" и записи, добавленные вручную в собственных приложениях.
Полный список требований к параметрам, а также примеры запросов и ответов можно найти в разделе Фильтрация по семейству источников данных руководства по фильтрации данных.
Период агрегирования и хранение данных
Хотя конечная точка rollUp принимает любое значение windowSize, равное 1 секунде ("1s") или больше, разные типы данных записывают и сохраняют измерения с разной частотой дискретизации или длительностью интервала в базовом хранилище. Например, показатели физической активности, такие как steps, distance, active-minutes и active-energy-burned, обычно записываются с интервалом в 1 минуту (60s).
В таблице ниже приведены разрешения базового хранилища и минимальные рекомендуемые значения windowSize для распространенных типов данных.
| Разрешение на хранение | Рекомендуемый минимум: windowSize |
Типы данных |
|---|---|---|
1 секунда (1s) |
"1s" |
heart-rate |
1 минута (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 |
При агрегировании типов данных интервала конечная точка rollUp помещает каждый записанный элемент данных в сегмент, содержащий startTime элемента данных. API не разбивает, не интерполирует и не распределяет данные интервала по сегментам субинтервалов.
Если вы укажете значение windowSize, которое меньше интервала хранения данных (например, запросите 10-секундное окно для steps, хранящихся с интервалом в 1 минуту):
- Первый подсегмент, соответствующий
startTimeинтервала (например,10:00:00–10:00:10), получает все данные, накопленные за минуту (например, все 100 шагов, зарегистрированных за эту минуту). - Остальные подсегменты в пределах той же минуты (с
10:00:10до10:00:20, с10:00:20до10:00:30и т. д.) не получают элементов данных, поскольку в этих окнах не начинается ни один интервал.
Это приводит к резким скачкам данных, когда значение всего интервала концентрируется в первом подокне, как показано на рисунке 1.
Чтобы получить равномерно распределенные и значимые агрегированные данные, всегда устанавливайте для windowSize продолжительность, равную или превышающую разрешение базового хранилища целевого типа данных (например, "60s" или больше для steps). Сведения о разрешении хранилища и минимальном рекомендуемом окне свертки для каждого типа данных можно найти в справочнике Типы данных Google Health API.
Группировка, когда диапазон не кратен размеру окна
Если запрашиваемый диапазон не кратен windowSize (или windowSizeDays), то последний хронологический сегмент усекается по верхней конечной точке диапазона и охватывает период, который короче размера окна. API принимает запрос без изменений и не выполняет округление, сдвиг по времени или интерполяцию данных.
Чтобы охватить весь запрошенный диапазон, API использует деление с округлением в большую сторону для вычисления общего количества окон агрегирования:
Number of windows = ceiling(Range duration / Window size)
Каждый сегмент начинается последовательно с начала диапазона. Если добавление ещё одного полноразмерного окна выходит за рамки запрошенного времени окончания, последнее окно усекается (ограничивается) по времени окончания диапазона.
Как работает группировка
Если вы запрашиваете сводки с неделимыми диапазонами, API применяет следующие правила:
- Группировка начинается с начала запрошенного диапазона (
range.startTimeилиrange.start) и продолжается вперед на размер окна (windowSizeилиwindowSizeDays). - Последний хронологический сегмент ограничен концом запрошенного диапазона (
range.endTimeилиrange.end) и охватывает более короткий период, чем запрошенный размер окна. - Возвращенные объекты
RollupDataPointилиDailyRollupDataPointвключают собственные явные временные метки начала и окончания, которые можно использовать для проверки фактической продолжительности усеченного сегмента. - Поскольку API возвращает сводные данные в обратном хронологическом порядке (сначала самые новые), последний хронологический сегмент (усеченный сегмент) отображается как первый элемент (
index 0) в возвращенном списке.
На рисунке 2 показано, как API разбивает на сегменты неделимый диапазон, начиная с range.startTime, ограничивает последний сегмент на range.endTime и возвращает полученные сегменты в обратном хронологическом порядке.
Пример 12-минутного диапазона с 5-минутным окном
Предположим, клиент запрашивает сводку за 12-минутный диапазон с 5-минутным windowSize ("300s"):
- Значение
range.startTime–10:00:00Z. - Значение
range.endTimeравно10:12:00Z, а общая продолжительность – 12 минут. - Значение
windowSize–"300s"(5 минут).
Поскольку 12 минут не делятся на 5 минут (12 = 5 * 2 + 2) без остатка, API вычисляет количество окон как ceiling(12 / 5) = 3. В результате получается
три хронологических сегмента:
| Сегмент | Интервал | Продолжительность | Статус периода |
|---|---|---|---|
| Сегмент 1 | [10:00:00Z, 10:05:00Z) |
5 минут | Полное окно |
| Сегмент 2 | [10:05:00Z, 10:10:00Z) |
5 минут | Полное окно |
| Сегмент 3 | [10:10:00Z, 10:12:00Z) |
2 минуты | Обрезано на range.endTime |
Влияние на агрегированные значения
Поскольку последний хронологический период имеет меньшую продолжительность, аддитивные показатели (такие как сумма или количество шагов) в усеченном сегменте ниже из-за более короткого промежутка времени.
Если пользователь идет в постоянном темпе 100 шагов в минуту в течение всего 12-минутного интервала, сегменты будут содержать следующие итоговые значения:
- В сегменте 1 (
10:00:00Z–10:05:00Z) регистрируется 500 шагов (5 минут по 100 шагов в минуту). - Вторая группа (
10:05:00Z–10:10:00Z) – 500 шагов (5 минут по 100 шагов в минуту). - В сегменте 3 (с
10:10:00Zдо10:12:00Z) зарегистрировано 200 шагов (2 минуты по 100 шагов в минуту).
Меньшее количество шагов (200) в сегменте 3 связано с двухминутной продолжительностью усеченного окна, а не со снижением активности пользователя. При построении графиков или анализе этих данных нормализуйте количество, используя явную продолжительность каждого сегмента, чтобы избежать вводящего в заблуждение падения действий пользователя.
На рисунке 3 сравнивается общее количество шагов (countSum) с нормализованными по продолжительности показателями в трех группах.
Пример ответа API с указанием порядка
Поскольку API возвращает результаты в обратном хронологическом порядке, усеченный сегмент будет первым элементом в списке:
{
"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"
}
}
]
}