Google Health API cung cấp các điểm cuối tổng hợp chuyên dụng để nhóm và tóm tắt hồ sơ sức khoẻ theo khoảng thời gian. Thay vì truy xuất và tính tổng các bản ghi thô riêng lẻ trên ứng dụng, hãy sử dụng các điểm cuối tổng hợp để tính toán các chỉ số (chẳng hạn như tổng, trung bình, tối thiểu và tối đa) trên một luồng dữ liệu đã điều chỉnh:
- Điểm cuối
rollUptổng hợp các điểm dữ liệu theo khoảng thời gian thực tế theo giờ UTC bằng cách sử dụng khoảng thời gian của cửa sổ có thể định cấu hình tính bằng giây (windowSize). - Điểm cuối
dailyRollUptổng hợp các điểm dữ liệu trên một hoặc nhiều ngày theo lịch (windowSizeDays) bằng cách sử dụng giờ dân sự tương ứng với đồng hồ địa phương của người dùng.
Cả hai điểm cuối đều tự động điều chỉnh các điểm dữ liệu trùng lặp trên các thiết bị được kết nối và loại trừ khoảng thời gian không đeo đối với các loại dữ liệu thiết bị đeo hỗ trợ tính năng phát hiện khi đeo.
So sánh các điểm cuối tổng hợp
Chọn điểm cuối tổng hợp phù hợp với cách ứng dụng của bạn nhóm và hiển thị các chỉ số sức khoẻ theo chuỗi thời gian:
| Tính năng | điểm cuối rollUp |
điểm cuối dailyRollUp |
|---|---|---|
| Yêu cầu 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 |
| Biểu diễn thời gian | Thời gian thực theo giờ UTC (startTime và endTime ở định dạng RFC 3339). |
Giờ dân sự (start và end dưới dạng đối tượng CivilDateTime). |
| Tham số cửa sổ | windowSize (thời lượng bắt buộc của chuỗi tính bằng giây, tối thiểu là "1s"). |
windowSizeDays (số ngày nguyên không bắt buộc, mặc định là 1). |
| Đối tượng phản hồi | RollupDataPoint |
DailyRollupDataPoint |
| Thứ tự phản hồi | Thứ tự thời gian đảo ngược (cửa sổ mới nhất trước). | Thứ tự thời gian đảo ngược (cửa sổ mới nhất trước). |
| Phù hợp nhất cho | Biểu đồ trong ngày, biểu đồ tần suất theo giờ hoặc phút và thông tin phân tích theo giờ UTC trong khoảng thời gian cố định. | Trang tổng quan hằng ngày, xu hướng trong nhiều ngày và thông tin tóm tắt có tính đến việc di chuyển giữa các múi giờ hoặc Giờ mùa hè. |
Cả hai điểm cuối đều thực thi giới hạn phạm vi truy vấn tối đa dựa trên loại dữ liệu:
- Phạm vi truy vấn tối đa là 14 ngày áp dụng cho
calories-in-heart-rate-zone,heart-rate,active-minutesvàtotal-calories. - Phạm vi truy vấn tối đa là 90 ngày áp dụng cho tất cả các loại dữ liệu được hỗ trợ khác.
Để kiểm tra xem loại dữ liệu nào hỗ trợ rollup và dailyRollup, hãy xem tài liệu tham khảo về các loại dữ liệu của Google Health API.
Tổng hợp theo khoảng thời gian thực tế
Sử dụng điểm cuối rollUp để tổng hợp các điểm dữ liệu trong một khoảng thời gian thực tế range (theo giờ UTC) được nhóm theo thời lượng của khoảng thời gian tính bằng giây (windowSize).
Khi gọi điểm cuối rollUp, hãy cung cấp nội dung yêu cầu JSON chứa range đóng-mở (bao gồm startTime, không bao gồm endTime) và windowSize. Hãy lưu ý các yêu cầu sau đây về windowSize:
- Thời lượng
windowSizephải ít nhất là 1 giây ("1s"). API từ chối thời lượng dưới một giây, bằng 0 hoặc âm kèm theo lỗi400 Bad Request(INVALID_ROLLUP_WINDOW). - Để tránh việc phân phối không đồng đều dữ liệu tổng hợp trên các nhóm phụ, hãy chọn một
windowSizebằng hoặc lớn hơn độ phân giải bộ nhớ cơ bản của loại dữ liệu (chẳng hạn như"60s"cho khoảng thời gian bước 1 phút). Để biết thông tin chi tiết, hãy xem phần Cửa sổ tổng hợp và độ phân giải bộ nhớ.
Ví dụ: yêu cầu sau đây tổng hợp số bước trong khoảng thời gian 1 phút (60s):
Yêu cầu
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"
}Phản hồi
{
"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"
}
},
...
]
}Tổng hợp theo ngày dương lịch
Sử dụng điểm cuối dailyRollUp để tổng hợp dữ liệu trong một ngày dương lịch hoặc nhiều ngày (windowSizeDays). Cung cấp giờ dân sự đóng-mở range (start và end) trong nội dung yêu cầu. Tuỳ thuộc vào loại dữ liệu, điểm cuối sẽ trả về các giá trị tổng hợp như tổng hoặc trung bình trong mỗi khoảng thời gian dân sự.
Vì dailyRollUp hoạt động theo giờ dân sự bằng cách sử dụng độ lệch UTC được ghi lại với mỗi điểm dữ liệu, nên hàm này sẽ tự động điều chỉnh độ dài ngày thay đổi do quá trình chuyển đổi Giờ mùa hè hoặc di chuyển giữa các múi giờ.
Ví dụ: yêu cầu sau đây tổng hợp số bước trong một ngày dương lịch (windowSizeDays: 1):
Yêu cầu
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
}Phản hồi
{
"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"
}
}
]
}Tổng hợp theo nhóm nguồn dữ liệu
Cả rollUp và dailyRollUp đều chấp nhận trường dataSourceFamily không bắt buộc trong nội dung yêu cầu JSON để hạn chế việc tổng hợp cho các nhóm nguồn cụ thể:
- Lựa chọn
users/me/dataSourceFamilies/all-sources(mặc định) tổng hợp dữ liệu được đối chiếu trên tất cả các nguồn bên thứ nhất và bên thứ ba đã đăng ký. - Lựa chọn
users/me/dataSourceFamilies/google-wearablestổng hợp dữ liệu do các thiết bị theo dõi đeo được của Google và Fitbit ghi lại, không bao gồm dữ liệu được ghi lại theo cách thủ công và dữ liệu do điện thoại ước tính. - Lựa chọn
users/me/dataSourceFamilies/google-sourcestổng hợp dữ liệu từ các nguồn của bên thứ nhất là Google và Fitbit, bao gồm cả thiết bị theo dõi đeo trên người, Health Connect và các mục nhập thủ công trong ứng dụng của bên thứ nhất.
Để biết đầy đủ các yêu cầu về tham số cũng như các ví dụ về yêu cầu và phản hồi, hãy xem phần Lọc theo nhóm nguồn dữ liệu trong hướng dẫn Lọc dữ liệu.
Cửa sổ tổng hợp và độ phân giải của bộ nhớ
Mặc dù điểm cuối rollUp chấp nhận mọi windowSize từ 1 giây ("1s") trở lên, nhưng các loại dữ liệu khác nhau sẽ ghi lại và duy trì các phép đo ở các tốc độ lấy mẫu hoặc khoảng thời gian khác nhau trong bộ nhớ cơ bản. Ví dụ:
các chỉ số hoạt động thể chất trên thiết bị đeo như steps, distance,
active-minutes và active-energy-burned thường được ghi lại theo khoảng thời gian 1 phút
(60s).
Bảng sau đây liệt kê độ phân giải bộ nhớ cơ bản và giá trị windowSize tối thiểu được đề xuất cho các loại dữ liệu phổ biến:
| Giải pháp về bộ nhớ | Mức tối thiểu nên dùng là windowSize |
Loại dữ liệu |
|---|---|---|
1 giây (1s) |
"1s" |
heart-rate |
1 phút (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 |
Khi tổng hợp các loại dữ liệu khoảng thời gian, điểm cuối rollUp sẽ đặt từng điểm dữ liệu được ghi lại vào bộ chứa chứa startTime của điểm dữ liệu. API này không phân chia, nội suy hoặc phân phối dữ liệu khoảng thời gian trên các bộ chứa khoảng thời gian phụ.
Nếu bạn chỉ định một windowSize nhỏ hơn khoảng thời gian lưu trữ dữ liệu cơ bản (ví dụ: yêu cầu khoảng thời gian 10 giây cho steps được lưu trữ theo khoảng thời gian 1 phút):
- Nhóm phụ đầu tiên khớp với
startTimecủa khoảng thời gian (ví dụ:10:00:00đến10:00:10) sẽ nhận được số lượng tích luỹ của toàn bộ phút (ví dụ: tất cả 100 bước được ghi lại cho phút đó). - Các nhóm phụ còn lại trong cùng một phút (
10:00:10đến10:00:20,10:00:20đến10:00:30, v.v.) không nhận được điểm dữ liệu nào vì không có khoảng thời gian nào bắt đầu trong các khoảng thời gian đó.
Điều này tạo ra dữ liệu tăng đột biến, trong đó toàn bộ giá trị của khoảng thời gian được tập trung vào cửa sổ phụ đầu tiên, như minh hoạ trong Hình 1.
Để có được các dữ liệu tổng hợp có ý nghĩa và được phân phối đồng đều, hãy luôn đặt windowSize thành một khoảng thời gian bằng hoặc lớn hơn độ phân giải bộ nhớ cơ bản của loại dữ liệu mục tiêu (ví dụ: "60s" trở lên cho steps). Để biết độ phân giải bộ nhớ và khoảng thời gian tổng hợp tối thiểu được đề xuất cho từng loại dữ liệu, hãy xem tài liệu tham khảo về các loại dữ liệu của Google Health API.
Phân nhóm khi phạm vi không phải là bội số của kích thước cửa sổ
Nếu phạm vi được yêu cầu không phải là bội số chính xác của windowSize (hoặc windowSizeDays), thì bộ chứa theo trình tự thời gian cuối cùng sẽ bị cắt bớt ở điểm cuối trên của phạm vi và bao gồm một khoảng thời gian ngắn hơn kích thước của khoảng thời gian. API chấp nhận yêu cầu của bạn mà không cần sửa đổi và không thực hiện làm tròn, dịch chuyển thời gian hoặc nội suy dữ liệu.
Để bao gồm toàn bộ phạm vi được yêu cầu, API sử dụng phép chia làm tròn lên để tính tổng số khoảng thời gian tổng hợp:
Number of windows = ceiling(Range duration / Window size)
Mỗi bộ chứa bắt đầu tuần tự từ đầu phạm vi của bạn. Nếu việc thêm một cửa sổ có kích thước đầy đủ khác vượt quá thời gian kết thúc mà bạn yêu cầu, thì cửa sổ cuối cùng sẽ bị cắt bớt (bị kẹp) tại thời gian kết thúc của phạm vi.
Cách hoạt động của tính năng phân nhóm
Khi bạn yêu cầu dữ liệu tổng hợp có phạm vi không chia hết, API sẽ áp dụng các quy tắc sau:
- Việc phân nhóm bắt đầu từ đầu phạm vi bạn yêu cầu (
range.startTimehoặcrange.start) và tiến dần theo kích thước cửa sổ (windowSizehoặcwindowSizeDays). - Nhóm theo trình tự thời gian cuối cùng được giới hạn ở cuối phạm vi bạn yêu cầu (
range.endTimehoặcrange.end), bao gồm khoảng thời gian ngắn hơn kích thước cửa sổ được yêu cầu. - Các đối tượng
RollupDataPointhoặcDailyRollupDataPointđược trả về bao gồm dấu thời gian bắt đầu và kết thúc rõ ràng, bạn có thể sử dụng dấu thời gian này để kiểm tra thời lượng thực tế của nhóm bị cắt bớt. - Vì API trả về dữ liệu tổng hợp theo thứ tự thời gian đảo ngược (mới nhất trước tiên), nên bộ chứa theo trình tự thời gian cuối cùng (bộ chứa bị cắt bớt) sẽ xuất hiện dưới dạng phần tử đầu tiên (
index 0) trong danh sách được trả về.
Hình 2 minh hoạ cách API phân nhóm một phạm vi không chia hết từ range.startTime, cố định nhóm cuối cùng tại range.endTime và trả về các nhóm kết quả theo thứ tự thời gian đảo ngược.
Ví dụ về phạm vi 12 phút với khoảng thời gian 5 phút
Giả sử một ứng dụng yêu cầu tổng hợp trong phạm vi 12 phút với windowSize ("300s") là 5 phút:
- Giá trị
range.startTimelà10:00:00Z. - Giá trị
range.endTimelà10:12:00Z, cho tổng thời lượng là 12 phút. - Giá trị
windowSizelà"300s"(5 phút).
Vì 12 phút không phải là bội số chính xác của 5 phút (12 = 5 * 2 + 2), nên API sẽ tính số lượng cửa sổ là ceiling(12 / 5) = 3. Thao tác này sẽ tạo ra ba nhóm theo trình tự thời gian:
| Bộ chứa | Khoảng cách | Thời lượng | Trạng thái khung thời gian |
|---|---|---|---|
| Nhóm 1 | [10:00:00Z, 10:05:00Z) |
5 phút | Toàn bộ cửa sổ |
| Nhóm 2 | [10:05:00Z, 10:10:00Z) |
5 phút | Toàn bộ cửa sổ |
| Nhóm 3 | [10:10:00Z, 10:12:00Z) |
2 phút | Đã cắt bớt lúc range.endTime |
Tác động đến giá trị tổng hợp
Vì khoảng thời gian cuối cùng theo trình tự thời gian có thời lượng ngắn hơn, nên các chỉ số cộng dồn (chẳng hạn như tổng hoặc số bước) sẽ thấp hơn trong bộ chứa bị cắt bớt do khoảng thời gian ngắn hơn.
Nếu người dùng đi bộ với tốc độ ổn định là 100 bước mỗi phút trong toàn bộ khoảng thời gian 12 phút này, thì các bộ chứa sẽ có tổng số bước như sau:
- Nhóm 1 (
10:00:00Zđến10:05:00Z) ghi lại 500 bước (5 phút với 100 bước mỗi phút). - Nhóm 2 (
10:05:00Zđến10:10:00Z) ghi lại 500 bước (5 phút với 100 bước mỗi phút). - Nhóm 3 (
10:10:00Zđến10:12:00Z) ghi lại 200 bước (2 phút với 100 bước mỗi phút).
Số bước thấp hơn (200 bước) trong Nhóm 3 là do thời lượng 2 phút của khoảng thời gian bị cắt bớt, chứ không phải do hoạt động của người dùng giảm. Khi vẽ biểu đồ hoặc phân tích dữ liệu này, hãy chuẩn hoá số lượng bằng cách sử dụng thời lượng rõ ràng của mỗi bộ chứa để tránh trình bày mức giảm gây hiểu lầm trong hoạt động của người dùng.
Hình 3 so sánh tổng số bước cộng dồn thô (countSum) với tỷ lệ chuẩn hoá theo thời lượng trên ba nhóm.
Ví dụ về phản hồi của API cho thấy thứ tự
Vì API trả về kết quả theo thứ tự thời gian đảo ngược, nên bộ chứa bị cắt bớt sẽ xuất hiện dưới dạng phần tử đầu tiên trong danh sách được trả về:
{
"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"
}
}
]
}