Skip to Content
操作指南連結、彙總與查找

用連結、彙總與查找串起兩張表

情境:專案表要指向客戶表,並在不複製資料的情況下顯示客戶名稱與預算。

前置條件

你需要相關資料表的建表權限,以及來源表的 moderator、兩張表的資料列讀寫權限。本例把兩張表都放在聊天室 11111111-1111-4111-8111-111111111111。一般情況下,link 可以留在來源表的相同 scope,也可以在同公司內往上連:chatroom → 自己的 department/company,department → 自己的 company;向下、同層 sibling、無關 department 與跨公司目標都會被拒絕。以下 private 請求使用使用者 access token。

Chatroom table 的向上 link,現在會讓 rollup、lookup 與符合條件的 lookup fallback 依聊天室的有效公司解析,回傳可讀目標值。不存在、不可讀或跨公司的目標仍不會提供值。Link preview 也依同一有效公司驗證;計算欄 preview 若遇到精確 decimal 無效運算或溢位,會回 400 並帶字串 detail。

步驟

1. 建立目標表與來源表

先透過 tables.create 建立「客戶」,再建立「專案」。記下兩個回應中的 id,以及客戶表 settings.column_mapping 裡「名稱」與「預算」的內部 ID。

POST /private/module/custom_tables/chatroom/11111111-1111-4111-8111-111111111111/tables Content-Type: application/json { "name": "客戶", "description": "專案客戶主檔", "schema_definition": { "columns": [ { "name": "名稱", "type": "string", "required": true }, { "name": "預算", "type": "float" } ] } }
POST /private/module/custom_tables/chatroom/11111111-1111-4111-8111-111111111111/tables Content-Type: application/json { "name": "專案", "description": "進行中的客戶專案", "schema_definition": { "columns": [ { "name": "專案名稱", "type": "string", "required": true } ] } }

以下假設客戶表是 22222222-2222-4222-8222-222222222222、專案表是 33333333-3333-4333-8333-333333333333。

columns.create 在這一步定義關係:target_table_id 指向客戶表;cardinality: "one" 表示一個專案只選一位客戶。保留回應中的 link 欄位 column.id。

POST /private/module/custom_tables/chatroom/11111111-1111-4111-8111-111111111111/tables/33333333-3333-4333-8333-333333333333/columns Content-Type: application/json { "name": "客戶", "type": "link", "target_table_id": "22222222-2222-4222-8222-222222222222", "cardinality": "one" }

以下使用 link 欄位 ID col_44444444_4444_4444_8444_444444444444。

3. 建立 rollup 與 lookup

依 columns.create 的欄位契約,link_field 與 target_column 都使用內部 ID:前者固定關係,後者即使顯示名稱改名仍可正確計算。rollup 對預算做 sum;lookup 原樣帶回客戶名稱。兩者都是唯讀計算欄位。

POST /private/module/custom_tables/chatroom/11111111-1111-4111-8111-111111111111/tables/33333333-3333-4333-8333-333333333333/columns Content-Type: application/json { "name": "客戶預算", "type": "rollup", "link_field": "col_44444444_4444_4444_8444_444444444444", "target_column": "col_55555555_5555_4555_8555_555555555555", "aggregation": "sum" }
POST /private/module/custom_tables/chatroom/11111111-1111-4111-8111-111111111111/tables/33333333-3333-4333-8333-333333333333/columns Content-Type: application/json { "name": "客戶名稱", "type": "lookup", "link_field": "col_44444444_4444_4444_8444_444444444444", "target_column": "col_66666666_6666_4666_8666_666666666666" }

不要在資料列建立或更新請求中傳入 rollup/lookup 值;伺服器會從 link 關係計算它們。

使用 records.create 先建立客戶並保留資料列 id,再建立專案。資料列建立可用顯示名稱當 key;link 值即使 cardinality 是 one,仍以目標 record ID 陣列傳入。

POST /private/module/custom_tables/chatroom/11111111-1111-4111-8111-111111111111/tables/22222222-2222-4222-8222-222222222222/records Content-Type: application/json { "data": { "名稱": "北辰商事", "預算": 1250000 }, "created_by_ai": false }
POST /private/module/custom_tables/chatroom/11111111-1111-4111-8111-111111111111/tables/33333333-3333-4333-8333-333333333333/records Content-Type: application/json { "data": { "專案名稱": "網站重構", "客戶": ["77777777-7777-4777-8777-777777777777"] }, "created_by_ai": false }

以下假設專案 record ID 是 88888888-8888-4888-8888-888888888888。

5. 讀取 hydrated 關係

records.hydrated 會一次回傳目前 record、可讀的反向關係、表格資訊,並可展開 link 目標。

GET /private/module/custom_tables/chatroom/11111111-1111-4111-8111-111111111111/tables/33333333-3333-4333-8333-333333333333/records/88888888-8888-4888-8888-888888888888/hydrated?expand_links=true&limit_per_table=20

已登入的產品也可從絕對路徑 GET /private/module/custom_tables/linked-records/guide 取得嵌入式 Markdown 說明,目錄項目是 guide.linkedRecordsGuide。本頁將該說明的核心關係模型改寫為可執行流程,並以目前 catalog 修正過時限制。

與舊版連結說明不同,現在計算欄位是可以篩選與排序的——REST 這一側走 records.search 或已儲存檢視,而從這個版本起,agent 那一側也可以了。下一節就是精確的適用範圍;不要把舊版「一律不可篩選」當成現況。

對剛建好的計算欄位篩選與排序

AI 現在可以在伺服器端回答「預算彙總超過 10000 的客戶」與「客戶預算最大的十個專案」。以前它是把整張表一頁一頁抓下來、在腦袋裡比對 rollup 格子——只要超過第一頁就是錯的——而且隨附的 cheat sheet 明白告訴它計算欄位在查詢上是唯讀的。兩側都編譯成同一組關聯子查詢下推,所以 ACL 底線與 null 語意完全一致。

真正符合資格的範圍比「計算欄位」窄:

欄位篩選排序
rollup、cardinality 為 one 且沒有 fallback 的 lookup可可
已 picked 且沒有 fallback 的 cardinality-many lookup可可
formula——四則運算、比較、UPPER、LOWER、LEN、精確小數函式可可
含 IF、AND、OR、CONCAT、日期函式、[Link -> Column] 引用,或以 fallback lookup 為輸入的 formula不可不可
link 欄位本身可判斷成員(eq / in 目標紀錄 ID)與有無(is_empty / is_not_empty)永遠不可

含 IF、AND、OR、CONCAT、TODAY、DATEDIFF、YEAR 或 MONTH 的 formula 在兩條路徑上都會被拒絕:IF/AND/OR formulas cannot be sorted/filtered yet; sort/filter is available on plain arithmetic/comparison/UPPER/LOWER/LEN formulas。[Link -> Column] 引用會被拒絕,訊息為 cross-table refs cannot be sorted/filtered; declare a cardinality-one numeric LOOKUP column and sort/filter that;帶有 fallback 的 lookup,或讀取它的 formula,則只能在求值時計算(eval-only)。以比較為根的 formula 輸出是布林值,因此只吃 eq、neq、is_null、is_not_null,而且值必須是真正的 true/false。decimal 的 rollup、lookup 或 formula 要用像 "10000.00" 的小數字串比較;若範圍內有列無法精確求值,請求會以 ct.numeric_overflow 或 ct.numeric_invalid 失敗。使用乘法、DECIMAL、QUANTIZE 或 DIVIDE 的 decimal formula,在篩選與排序時會編譯成精確的 SQL;無法精確編譯時,REST 回 400 computed decimal expression is not exactly SQL-representable: <reason>(篩選比較則是對應的 computed decimal comparison is not exactly SQL-representable: <reason>)。

link 欄位仍然永遠不能排序。在 agent 這一側,拒絕訊息現在是 link 專用的——Column '<c>' is a link column and cannot be sorted on — use custom_tables_traverse_links for link analysis.——而 cardinality 為 one 的 link 在那裡可以當聚合的 group_by 鍵,只是分組鍵是目標 record id 而不是名稱,而且 NULL 那一組刻意把三種情況混在一起:這一列沒有連結、目標被軟刪除、或呼叫者的 scope 看不到目標。

兩側共用同一道硬上限:50,000 筆存活資料列。超過就直接拒絕,不會退化、不會分頁、也沒有備援:

computed filters are refused on tables with more than 50000 live records (this table has <N>) — narrow the data with regular filters first sorting by computed columns is refused on tables with more than 50000 live records (this table has <N>) — narrow the data with regular filters first

這句補救建議要抱著懷疑讀。那個筆數是在任何條件編譯之前就檢查的,所以再加一般 filters 也解不開這道閘;只有換一張比較小的表才行。

另一個陷阱是 null,而且它正是這一頁該提 ACL 的理由。計算欄位的格子在「link 解不到東西」與「呼叫者讀不到那張受管的目標表」兩種情況下都是 null,而 null 格子只會被 is_null 命中,其他運算子一律不中。所以「沒有客戶預算的專案」會默默把「客戶是呼叫者看不到的那些」專案也算進去。任一側單次請求最多 AND 三個計算欄位條件。REST 的參數形狀見查詢模型,工具參數與錯誤字串見 Agent 工具箱。

你會看到什麼

專案資料列的 link 指向「北辰商事」,lookup 顯示客戶名稱,rollup 顯示 1250000.0(float 的加總)。expand_links=true 時,expanded 會把每個 link 欄的顯示名稱對應到 { total, records }:total 是 live 連結目標的實際數量,records 依連結順序最多列出 50 筆;呼叫者無權讀取的目標——以及呼叫者對目標表的讀取層級為 filtered 時的所有目標——只會是只有 ID 的 stub,帶 readable: false 且 data 為空。反向連結不會繞過來源表 ACL:來自呼叫者無權讀取、或其 link 欄位在來源表上對呼叫者被隱藏之來源表的群組會被省略,被隱藏的 link 欄位也不會出現在 expanded。

常見錯誤

請直接查看欄位建立錯誤表、資料列建立錯誤表與hydrated read 錯誤表。

試試看

流程精靈可執行兩表、link、rollup 與 hydrated read 的基本流程;再用 API Playground 補上本例的 lookup 欄位。

Last updated on