iT邦幫忙

0

【kintone】取得大量記錄-三種實作方法的限制與比較

  • 分享至 

  • xImage
  •  

在 kintone 的開發中,最常遇到的限制之一,就是「如何一次抓到大量記錄」。
由於「取得複數記錄的 API」(GET /k/v1/records.json)單次可取得的記錄數最高上限為 500 筆,若要一次取得更多的記錄,就必須運用其他方法來達成。

本文整理 3 種官方推薦的常見策略,並說明原理、適用場景與限制。開發者可評估其使用情境,選擇更有效率、風險更低的方式來大量取得記錄。最後也會介紹更簡潔的做法──使用 kintoneRestAPIClient 的批次取得功能。

基本思路

大量取得記錄的方式主要有三種:

方法1:利用記錄號碼($id)

適用於:

  • 不需要特殊排序
  • recordId($id)排序即可滿足需求 的情境。

方法2:使用 Cursor API

適用於:

  • 需要複雜排序
  • 並且 預估資料量會超過 10,000 筆 的情況。

方法3:使用 offset 分頁

適用於:

  • 取得資料量預期 永遠不會超過 10,000 的情境。

若用流程圖來看,大致如下:

是否需要特殊排序?
   ├─ 否 → 使用「方法1:Record ID」
   └─ 是 → 是否超過 10,000 筆?
             ├─ 是 → 「方法2:Cursor API」
             └─ 否 → 「方法3:offset」

方法1:利用記錄號碼($id)

利用「取得複數記錄的 API」(GET /k/v1/records.json),以 order by $id asc 對記錄排序,並以「前一次最後取得的 recordId」作為下一次查詢條件。

例如:

query = "order by $id asc limit 500"
下一輪 query = " $id > 最後取得的ID order by $id asc limit 500"

其核心在於:

  1. 使用 $id 作為游標
  2. 每次都以 $id asc 排序

這個方式在資料庫領域稱為 Seek Method,比 offset 方式快很多,是通用的高效查詢策略。

適合的情境

✔ 不需要特別排序(只要 $id 順序即可)

例如:資料備份、外部系統同步、排程抓資料等。

✔ 如果你能在程式內再做第二次排序

若透過程式邏輯(例如 Node.js 取得後在記憶體中 sort),那麼這個方式依然適合。

理由

  • 速度快(線性時間):recordId 是索引鍵、連續遞增,因此查詢成本固定且穩定。
  • 不會發生 offset 的效能劣化問題:offset 越大越慢,但使用 $id > X 完全不受影響。

方法2:利用 Cursor API

「Cursor(游標)」 是資料庫中用來記錄「目前取得位置」的指標。
kintone 的 Cursor API 也是依此概念設計。

Cursor API:/k/v1/records/cursor

  • POST:建立 cursor,伺服器將回傳 cursorId
  • GET:透過 cursorId 取得記錄,透過 next 參數可判斷是否需要進行下一輪資料取得。
  • DELETE:透過 cursorId 刪除指定 cursor。

以 cursor 取的記錄的流程如下:

  1. 建立 Cursor(送出 app、query、fields、size 等資訊)
  2. 使用 cursorId 取得資料(透過 next 參數判斷是否繼續遞迴請求)
  3. 資料取得完後刪除 cursor(當該 cursor 可獲取的記錄已全數取得時,cursor 便會自動刪除)

Cursor 不會受 offset 限制,也不需靠 $id 排序。

適合的情境

✔ 需要複雜排序(多欄位排序、條件排序)
✔ 批次處理,且資料量已超過或預期會超過 10,000 筆
✔ 需要的 Cursor 數在限制以內

理由

  • 速度穩定:Cursor API 本身就是為了大量資料而設計,相較於使用 offset 的方法,無論排序條件或資料筆數,取得記錄的速度都能保持穩定。
  • 需注意限制每個 domain 最多可同時建立 10 個 cursor,因此不適合以下情境:
    • 前端 JS 客製化(多使用者同時操作容易導致 cursor 數超量)
    • 其他無法掌握 cursor 數量的場景

💡 當 domain 中存在的 cursor 數量已達 10 個,又嘗試呼叫 Create Cursor API 時,就會發生「429 Too Many Requests」的錯誤。

方法3:利用 offset

「取得複數記錄的 API」(GET /k/v1/records.json),調整 offsetlimit 逐段取得資料:

offset 0 → 500
offset 500 → 500
offset 1000 → 500
...

適合的情境

✔ 確定記錄數永遠不會超過 10,000 筆
✔ 可以接受 offset 分頁帶來的效能下降
✔ 最重視「實作簡單」

理由

offset 方式實作上最簡單,可以直接帶入篩選排序條件,也不需要處理 $id 或 cursor。
然而 offset 本身:

  • 查詢越往後越慢
  • API 限制 offset 上限值為 10,000

因此僅適合記錄數限定在一定範圍內的資料抓取。

💡 關於 offset 限制值

2020 年 7 月 12 日定期維護後,取得複數記錄 API 的 offset 上限統一設為 10,000
超過此限制時:

  • kintone 系統管理者、cybozu.com 共通管理者、該應用程式管理者
    會在列表頁面上看到警告訊息(每 30 天最多顯示一次)。
  • 若程式在這期間持續超過 offset 限制,依然會在 30 天後再次顯示。

詳細內容可參考官方公告。

推薦方法:使用官方 SDK

kintone 官方提供:

可以自動幫你處理:

  • offset / limit 的分頁
  • 或自動落實 Cursor API 分批讀取

你幾乎不需要考慮 offset 上限與分頁邏輯。

使用 kintoneRestAPIClient:record.getAllRecords

如果你是用 JavaScript/TypeScript 進行開發,建議優先考慮使用官方 SDK @kintone/rest-api-client 來取得大量記錄。
其中的 record.getAllRecords() 方法,會在內部自動幫你處理「超過 REST API 單次上限」的分批請求。

簡單來說,它會根據你指定的條件決定最合適的請求方式:

  • 未指定 orderBy 時,優先採取 $id 法。
  • 其次,有自訂排序且未額外指定 withCursor: false 時,採用 cursor 法。
  • 不符合上述兩種條件時,採取 offset 法。
const client = new KintoneRestAPIClient()

const records = await client.record.getAllRecords({
  app: 123,
  condition: '狀態 in ("完成")',
  orderBy: '更新時間 desc',
  withCursor: true // 預設為 true,會在需要時自動使用 Cursor API
});

主要參數說明

  • app
    指定要取得記錄的應用程式 ID(必填)。
  • fields
    要回傳的欄位代碼陣列。若省略,會回傳你有權限看到的所有欄位。
  • condition:用來篩選記錄的查詢字串。
    ✅ 可以指定條件(例如 狀態 in ("結束", "處理中")
    不能使用 order bylimitoffset(排序請用 orderBy 參數)
  • orderBy
    排序條件(例如:'更新時間 desc')。
    若有指定,SDK 會在內部自動選擇適合的方式(包含 Cursor API)來維持排序與效能。
  • withCursor(預設 true):
    是否允許在內部使用 Cursor API。
    通常建議保持預設值即可,不需要特別修改。

結語

在 kintone 中,「一次抓很多筆記錄」看似只是加個迴圈、多呼叫幾次 API 就能解決,但實務上會受到:

  • 單次取得上限(500 筆)
  • offset 上限(10,000)
  • Cursor 數量上限(每個 domain 最多 10 個)
  • 排序條件與效能(offset 越大越慢)

等多種因素影響。
如果忽略這些限制,輕則效能變慢,重則觸發系統警告,甚至導致整個批次流程不穩定。

可以簡單記住以下選擇指引:

  • 不需複雜排序、又在自己掌控的後端或批次程式中使用 → 優先用「方法1:記錄號碼($id)」
  • 需要複雜排序,且可能動輒超過 10,000 筆 → 用「方法2:Cursor API」
  • 資料量小、確定不會超過 10,000 筆,又只想快速做完 → 才考慮「方法3:offset」

而在實務開發中,若你是用 JavaScript/TypeScript,更推薦的做法,是直接交給 @kintone/rest-api-clientrecord.getAllRecords() 來處理。

只要先選對取得方式,後續的整合與維運都會輕鬆很多。


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言