ข้อมูลรวม

Google Health API มีปลายทางการรวมข้อมูลโดยเฉพาะที่จัดกลุ่มและสรุปบันทึกข้อมูลสุขภาพเป็นกรอบเวลา แทนที่จะดึงข้อมูลและรวมระเบียนดิบแต่ละรายการในไคลเอ็นต์ ให้ใช้ปลายทางการรวมเพื่อคำนวณเมตริก (เช่น ผลรวม ค่าเฉลี่ย ค่าต่ำสุด และค่าสูงสุด) ผ่านสตรีมข้อมูลที่ปรับยอดแล้ว ดังนี้

  • ปลายทาง rollUp จะรวบรวมจุดข้อมูลในช่วงเวลาจริงในรูปแบบ UTC โดยใช้ระยะเวลาของกรอบเวลาที่กำหนดค่าได้ในหน่วยวินาที (windowSize)
  • ปลายทาง dailyRollUp จะรวบรวมจุดข้อมูลในวันตามปฏิทินอย่างน้อย 1 วัน (windowSizeDays) โดยใช้เวลาตามกฎหมายที่สัมพันธ์กับนาฬิกาท้องถิ่นของผู้ใช้

ปลายทางทั้ง 2 รายการจะปรับยอดจุดข้อมูลที่ทับซ้อนกันในอุปกรณ์ที่เชื่อมต่อโดยอัตโนมัติ และยกเว้นช่วงเวลาที่ไม่ได้สวมใส่อุปกรณ์สำหรับประเภทข้อมูลที่สวมใส่ได้ซึ่งรองรับการตรวจจับการสวมใส่บนข้อมือ

เปรียบเทียบปลายทางการรวมข้อมูล

เลือกปลายทางการรวมข้อมูลที่ตรงกับวิธีที่แอปพลิเคชันจัดกลุ่มและแสดงตัวชี้วัดสุขภาพแบบอนุกรมเวลา ดังนี้

ฟีเจอร์ อุปกรณ์ปลายทาง 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 แบบระยะเวลาคงที่ แดชบอร์ดรายวัน เทรนด์แบบหลายวัน และข้อมูลสรุปที่พิจารณาการเดินทางข้ามเขตเวลาหรือเวลาออมแสง

ปลายทางทั้ง 2 แห่งจะบังคับใช้ขีดจำกัดช่วงการค้นหาสูงสุดตามประเภทข้อมูล ดังนี้

  • ช่วงการค้นหาสูงสุด 14 วันจะมีผลกับ calories-in-heart-rate-zone, heart-rate, active-minutes และ total-calories
  • ช่วงการค้นหาสูงสุด 90 วันจะมีผลกับข้อมูลประเภทอื่นๆ ที่รองรับทั้งหมด

หากต้องการตรวจสอบว่าข้อมูลประเภทใดรองรับ rollup และ dailyRollup โปรดดูข้อมูลอ้างอิงประเภทข้อมูล Google Health API

รวมตามช่วงเวลาจริง

ใช้ปลายทาง rollUp เพื่อรวบรวมจุดข้อมูลในช่วงเวลาจริง range (ในรูปแบบ UTC) ที่จัดกลุ่มตามระยะเวลาของกรอบเวลาเป็นวินาที (windowSize)

เมื่อเรียกใช้ปลายทาง rollUp ให้ระบุเนื้อหาคำขอ JSON ที่มี range แบบปิด-เปิด (รวม startTime ไม่รวม endTime) และ windowSize โปรดคำนึงถึงข้อกำหนดต่อไปนี้ของ windowSize

  • ระยะเวลา windowSize ต้องมีอย่างน้อย 1 วินาที ("1s") API จะปฏิเสธระยะเวลาที่น้อยกว่า 1 วินาที, ศูนย์ หรือระยะเวลาที่เป็นค่าลบพร้อมข้อผิดพลาด 400 Bad Request (INVALID_ROLLUP_WINDOW)
  • หากต้องการหลีกเลี่ยงการกระจายข้อมูลรวมที่ไม่สม่ำเสมอในบักเก็ตย่อย ให้เลือก windowSize ที่เท่ากับหรือมากกว่าความละเอียดของพื้นที่เก็บข้อมูลที่สำคัญของประเภทข้อมูล (เช่น "60s" สำหรับช่วงเวลาการก้าว 1 นาที) โปรดดูรายละเอียดที่หัวข้อกรอบเวลาการรวมข้อมูลและความละเอียดของพื้นที่เก็บข้อมูล

ตัวอย่างเช่น คำขอต่อไปนี้จะรวมจำนวนก้าวในช่วงเวลา 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 โดยตรง ซึ่งรวมถึงเครื่องมือติดตามที่สวมใส่ได้, Health Connect และข้อมูลที่ป้อนด้วยตนเองในแอปของ 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 นาที) ระบบจะดำเนินการดังนี้

  1. ที่เก็บข้อมูลย่อยแรกที่ตรงกับ startTime ของช่วงเวลา (เช่น 10:00:00 ถึง 10:00:10) จะได้รับจำนวนสะสมของทั้งนาที (เช่น จำนวนก้าวทั้งหมด 100 ก้าวที่บันทึกไว้สำหรับนาทีนั้น)
  2. บักเก็ตย่อยที่เหลือภายในนาทีเดียวกัน (10:00:10 ถึง 10:00:20, 10:00:20 ถึง 10:00:30 และอื่นๆ) จะไม่ได้รับจุดข้อมูล เนื่องจากไม่มีช่วงเวลาที่เริ่มต้นภายในกรอบเวลาเหล่านั้น

ซึ่งจะทำให้เกิดข้อมูลที่พุ่งสูงขึ้น โดยค่าของช่วงเวลาทั้งหมดจะกระจุกตัวอยู่ในหน้าต่างย่อยแรก ดังที่แสดงในรูปที่ 1

การจัดกลุ่มแบบรวมช่วงย่อยเทียบกับความละเอียดของพื้นที่เก็บข้อมูล
รูปที่ 1: การจัดกลุ่มข้อมูลสรุปช่วงย่อยซึ่งมีการกำหนดช่วงเวลา 1 นาทีให้กับที่เก็บข้อมูลย่อย 10 วินาทีแรกตาม startTime

หากต้องการรับข้อมูลรวมที่มีความหมายและกระจายอย่างสม่ำเสมอ ให้ตั้งค่า 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 และแสดงผลกลุ่มที่ได้ตามลำดับเวลาย้อนกลับ

การจัดกลุ่มแบบรวม การตัดทอน และการจัดลำดับการตอบกลับ
รูปที่ 2: การจัดกลุ่มแบบรวม การตัดทอนช่วงสิ้นสุด และการจัดลำดับการตอบกลับตามลำดับเวลาย้อนกลับ

ตัวอย่างช่วงเวลา 12 นาทีที่มีกรอบเวลา 5 นาที

สมมติว่าไคลเอ็นต์ขอข้อมูลสรุปในช่วง 12 นาทีโดยมี windowSize ("300s") 5 นาที ดังนี้

  • ค่า 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 ซึ่งจะสร้างที่เก็บข้อมูลตามลำดับเวลา 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 ก้าวต่อนาที)
  • กลุ่มที่ 2 (10:05:00Z ถึง 10:10:00Z) บันทึกได้ 500 ก้าว (5 นาทีที่ 100 ก้าวต่อนาที)
  • กลุ่มที่ 3 (10:10:00Z ถึง 10:12:00Z) บันทึก 200 ก้าว (2 นาทีที่ 100 ก้าวต่อนาที)

จำนวนก้าวที่ลดลงเหลือ 200 ก้าวในกลุ่มที่ 3 เกิดจากระยะเวลา 2 นาทีของหน้าต่างที่ถูกตัด ไม่ใช่กิจกรรมของผู้ใช้ที่ลดลง เมื่อวางแผนหรือวิเคราะห์ข้อมูลนี้ ให้ปรับจำนวนให้เป็นมาตรฐานโดยใช้ระยะเวลาที่ชัดเจนของแต่ละกลุ่มเพื่อหลีกเลี่ยงการแสดงกิจกรรมของผู้ใช้ที่ลดลงซึ่งทำให้เข้าใจผิด

รูปที่ 3 เปรียบเทียบจำนวนก้าวสะสมดิบ (countSum) กับอัตราที่ปรับมาตรฐานตามระยะเวลาในทั้ง 3 กลุ่ม

การเปรียบเทียบจำนวนก้าวทั้งหมดในกลุ่มข้อมูลดิบและอัตราจำนวนก้าวที่ปรับมาตรฐานแล้ว
รูปที่ 3: ผลรวมแบบบวกดิบเทียบกับอัตราที่ปรับให้สอดคล้องกับระยะเวลาสำหรับที่เก็บข้อมูลแบบ Rollup ที่ถูกตัด

ตัวอย่างการตอบกลับจาก 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"
      }
    }
  ]
}