1583 字
8 分鐘
n8n 踩坑筆記:為什麼 Code 節點的資料過濾沒有生效?

在使用 n8n 建立自動化工作流程時,Code 節點是最靈活且強大的工具之一。它讓我們能用 JavaScript 處理複雜的資料轉換和過濾邏輯。然而,當我嘗試使用 filter() 方法過濾資料時,卻遇到了一個令人困惑的問題:無論如何調整過濾邏輯,所有資料都沒有被移除

這個問題的根源出在哪裡?答案就藏在 n8n 的資料包裝機制中。

問題根源:n8n 的資料包裝機制#

n8n Item 資料結構#

當你在 n8n Code 節點中使用 $input.all() 取得資料時,每一個 item 並不是你期望的純資料物件,而是被 n8n 包裝過的特殊結構:

{
"json": {
"工作表名稱": [...] // 你的實際資料
},
"index": 0,
"pairedItem": { ... }
}

陷阱分析#

看看這段有問題的程式碼:

// ❌ 錯誤寫法
const result = data.filter(item => {
const itemKey = Object.keys(item)[0]; // 取得的是 "json",不是 "目標工作表"
return itemKey !== targetSheet; // 永遠為 true,因為 "json" !== "目標工作表"
});

為什麼沒有過濾掉任何資料?

讓我們用表格來對比預期與實際的情況:

情況預期取得的 Key實際取得的 Key判斷結果是否保留
目標 Sheet"目標工作表""json""json" !== "目標工作表"true✅ 保留
其他 Sheet"其他工作表名稱""json""json" !== "目標工作表"true✅ 保留

因為 Object.keys(item)[0] 抓到的永遠是 "json" 這個包裝層的 key,而不是你真正想要比對的資料 key,所以判斷永遠為 true,導致所有資料都被保留。

解決方案一:修正分離式寫法#

如果你想繼續使用 $input.all() 獲取資料,只需要多進入一層 .json 來取得真正的資料 Key。

❌ 錯誤程式碼#

// 取得要比對的 Sheet Name
const targetSheet = $('格式轉換1').first().json.query.sheet_name;
// 解析資料
let data = $input.all();
// 使用 filter 過濾
const result = data.filter(item => {
const itemKey = Object.keys(item)[0]; // ❌ 抓到 "json"
return itemKey !== targetSheet;
});
return result;

✅ 正確程式碼#

// 1. 取得要比對的 Sheet Name
const targetSheet = $('格式轉換1').first().json.query.sheet_name;
// 2. 解析資料
let data = $input.all();
// 3. 使用 filter 過濾
const result = data.filter(item => {
// 檢查 item.json 是否有內容,避免空資料報錯
if (!item.json) return false;
// ✅ 關鍵修正:要從 item.json 裡面抓 Key
const itemKey = Object.keys(item.json)[0];
// 邏輯:保留 Key 不等於 targetSheet 的項目
return itemKey !== targetSheet;
});
return result;
關鍵修正點

Object.keys(item)[0] 改為 Object.keys(item.json)[0],這樣才能取得真正的資料 key(例如 "工作表名稱"),而不是包裝層的 key("json")。

解決方案二:合併式處理(JSON.parse + filter)#

如果你的資料來源是字串格式(例如從其他節點傳遞過來的 JSON 字串),可以先用 JSON.parse() 解析,再進行過濾。這種方式的優勢是資料結構更簡潔,不需要處理 n8n 的包裝層。

資料結構的關鍵差異#

當你使用 JSON.parse 解析字串時,得到的是純 JavaScript 物件陣列,沒有 n8n 自動加上的 .json 外殼:

方法資料結構取得 Key 的方式
$input.all(){ json: { "工作表名稱": [...] }, index: 0, ... }Object.keys(item.json)[0]
JSON.parse(){ "工作表名稱": [...] }Object.keys(item)[0]

✅ 完整程式碼#

// 1. 取得要比對的 Sheet Name
const targetSheet = $('格式轉換1').first().json.query.sheet_name;
// 2. 解析資料
// 取得輸入的字串並轉成 JavaScript 陣列
let rawString = $input.first().json.data;
let parsedData = JSON.parse(rawString);
// 3. 使用 filter 過濾
// 注意:parsedData 是純 JS 陣列,沒有 n8n 的 .json 外殼,所以直接操作 item
const result = parsedData.filter(item => {
// 取得該項目的 Key (例如 "工作表名稱")
const itemKey = Object.keys(item)[0];
// 邏輯:保留 Key 不等於 targetSheet 的項目
return itemKey !== targetSheet;
});
// 4. 回傳結果
return result;
為什麼程式碼不一樣?
  • 分開寫時(使用 $input.all()):資料是 n8n 的 Item 格式,結構是 { json: { "工作表名稱": ... } },所以必須寫 item.json
  • 合併寫時(使用 JSON.parse):資料是你剛解析出來的純變數,結構直接是 { "工作表名稱": ... },所以直接用 item 即可。

兩種方案的適用場景#

方案適用情境優點缺點
方案一
修正 $input.all()
直接處理 n8n 節點間傳遞的資料原生支援,無需額外解析需要理解 n8n 包裝層
方案二
JSON.parse + filter
資料來源是 JSON 字串
需要更靈活的資料處理
資料結構簡潔,易於理解需要額外解析步驟

進階技巧:處理空陣列輸出#

在 n8n Code 節點中,如果你需要回傳一個空陣列的 JSON 檔案(例如當沒有資料需要處理時),不能直接回傳 [],而是需要遵循 n8n 的回傳格式:

❌ 錯誤寫法#

return []; // n8n 會將這視為沒有輸出

✅ 正確寫法#

return [
{
json: {
text: '[]', // 檔案內容就是這兩個字元
},
},
];
為什麼要這樣寫?

n8n 要求所有輸出都必須是 Item 陣列格式,即使是空資料也需要包裝成 { json: {...} } 的結構。如果直接回傳 [],n8n 會認為沒有任何輸出,後續節點可能無法正常執行。

總結與最佳實踐#

關鍵概念回顧#

  1. n8n Item 結構:每個 item 都被包裝成 { json: {...}, index: 0, pairedItem: {...} } 格式
  2. 取得資料 Key 的正確方式
    • 使用 $input.all()Object.keys(item.json)[0]
    • 使用 JSON.parse()Object.keys(item)[0]
  3. 空陣列輸出:必須回傳 [{ json: { text: '[]' } }] 格式

何時使用哪種方案?#

graph TD
A[需要過濾 n8n 資料] --> B{資料來源是?}
B -->|n8n 節點輸出| C[使用 $input.all<br/>取得 item.json]
B -->|JSON 字串| D[使用 JSON.parse<br/>直接操作物件]
C --> E[過濾完成]
D --> E
E --> F{有資料輸出?}
F -->|是| G[正常回傳 result]
F -->|否| H[回傳空陣列格式<br/>{json: {text: '[]'}}]

n8n Code 節點開發建議#

  1. 總是先確認資料結構:用 console.log(JSON.stringify(item, null, 2)) 檢查資料層級
  2. 善用空值檢查:在存取 item.json 前先確認它存在
  3. 理解包裝機制:記住 n8n 的資料永遠有一層 json 外殼
  4. 遵循回傳格式:所有輸出都應該是 [{ json: {...} }] 陣列格式

希望這篇文章能幫助你避開 n8n Code 節點的資料結構陷阱!如果你在使用 n8n 時遇到其他問題,歡迎交流。


參考資料:

n8n 官方文件 - Code 節點

n8n 踩坑筆記:為什麼 Code 節點的資料過濾沒有生效?
https://laplusda.com/posts/n8n-code-node-data-filter-pitfall/
作者
Zero
發佈於
2025-12-05
許可協議
CC BY-NC-SA 4.0
這篇文章有幫助嗎?

回報錯字、失效連結,或告訴我你想看的延伸主題。