【n8n教程】:掌握内置方法与变量,轻松驾驭数据处理

如果你已经在使用n8n构建自动化工作流,你会发现节点虽然功能强大,但有时候还是不够灵活。此时,n8n提供的内置方法与变量就成了你的"秘密武器"。

一、核心概念:表达式 vs Code节点

在深入学习方法之前,先理清两个重要的概念:

表达式(Expressions)

什么是表达式?

表达式是用{{ }}包裹的JavaScript代码片段,几乎可以在任何节点的任何字段中使用。

特点:

简单示例:


    
    
    
  // 获取当前时间戳
{{ $now.toISO() }}

// 条件判断

{{ $json.status === 'active' ? '活跃' : '离线' }}

// 访问其他节点的数据

{{ $("HTTP Request").first().json.userId }}

Code节点

什么是Code节点?

Code节点允许你编写多行JavaScript或Python代码来处理数据。相比表达式,它提供了更多的灵活性和计算能力。

特点:

简单示例:


    
    
    
  // 逐条处理模式:处理单个item
const
 orderData = $input.item.json;
const
 totalPrice = orderData.price * orderData.quantity;

return
 {
  ...orderData,
  totalPrice
: totalPrice
};

二、当前节点输入数据:json

这是最基础、也是最常用的一组方法。

关键方法总览

方法说明使用场景
$json当前item的JSON数据简写快速访问当前数据
$input.item当前处理的item完整对象需要访问item的所有属性
$input.all()获取所有input items在Code节点中批量处理
$input.first()获取第一个item只需要第一条数据
$input.last()获取最后一个item只需要最后一条数据
$binary当前item的二进制数据处理文件、图片等

实战例子1:数据验证与提取

假设你收到了一个包含用户信息的JSON数据:


    
    
    
  {
  "name"
: "张三",
  "email"
: "zhangsan@example.com",
  "age"
: 28,
  "status"
: "active"
}

需求:在后续节点中,只显示活跃用户的名字。

表达式解决方案:


    
    
    
  {{ $json.status === 'active' ? $json.name : '用户未激活' }}

Code节点解决方案:


    
    
    
  const user = $input.item.json;

if
 (user.status === 'active') {
  return
 {
    json
: {
      displayName
: user.name,
      userEmail
: user.email
    }
  };
} else {
  return
 {
    json
: {
      displayName
: '用户未激活',
      userEmail
: null
    }
  };
}

实战例子2:批量处理多条数据

Code节点中设置"Mode: Run Once for All Items",处理所有输入项:


    
    
    
  // 获取所有items
const
 allItems = $input.all();

// 提取每条数据的特定字段

const
 userNames = allItems.map(item => {
  return
 item.json.name;
});

// 返回处理结果

return
 [
  {
    json
: {
      totalUsers
: allItems.length,
      names
: userNames,
      firstUser
: $input.first().json.name,
      lastUser
: $input.last().json.name
    }
  }
];

三、访问其他节点的输出数据

当你需要在一个节点中引用之前节点的结果时,就需要这些方法。

关键方法总览

方法说明
$("<节点名>").all()获取指定节点的所有输出项
$("<节点名>").first()获取指定节点的第一个输出项
$("<节点名>").last()获取指定节点的最后一个输出项
$("<节点名>").item获取与当前item链接的上游item
$("<节点名>").params获取该节点的参数设置

实战例子3:合并多个节点的数据

假设你有两个API节点:

需求:在下游节点中合并这两个API的数据。

表达式方案:


    
    
    
  {{
  {
    user
: $("API Call 1").first().json,
    order
: $("API Call 2").first().json
  }
}}

Code节点方案:


    
    
    
  // 获取两个API节点的数据
const
 userData = $("API Call 1").first().json;
const
 orderData = $("API Call 2").first().json;

// 合并数据

return
 [
  {
    json
: {
      ...userData,
      ...orderData,
      mergedAt
: new Date().toISOString()
    }
  }
];

四、日期与时间处理:today

n8n内置了Luxon库来处理日期和时间,让复杂的时间操作变得简单。

关键方法总览

方法说明示例
$now当前时间(Luxon对象){{ $now.toISO() }}
$today今天午夜时刻{{ $today.toISODate() }}

实战例子4:时间戳与格式化


    
    
    
  // 获取当前时间戳
{{ $now.toISO() }}
// 输出:2025-12-05T11:11:00.000Z


// 格式化为中文日期

{{ $now.toFormat("yyyy年MM月dd日 HH:mm") }}
// 输出:2025年12月05日 11:11


// 计算7天后的日期

{{ $now.plus({ days: 7 }).toISODate() }}
// 输出:2025-12-12


// 判断是否是今天

{{ $json.timestamp > $today.toISO() ? '今天' : '之前' }}

五、高级数据查询:JMESPath

当你需要从复杂的JSON结构中提取特定数据时,JMESPath是最强大的工具。

基础语法


    
    
    
  $jmespath(expression, data)

常用查询模式


    
    
    
  // 1. 获取数组中的所有email
{{ $jmespath("users[*].email", $json) }}

// 2. 筛选符合条件的用户(年龄>18)

{{ $jmespath("users[?age > '18']", $json) }}

// 3. 获取嵌套对象的值

{{ $jmespath("address.city", $json) }}

// 4. 统计数组长度

{{ $jmespath("length(items)", $json) }}

// 5. 排序(按age升序)

{{ $jmespath("sort_by(users, &age)", $json) }}

实战例子5:从复杂数据中提取有效订单

假设你收到了这样的JSON数据:


    
    
    
  {
  "orders"
: [
    {
 "id": 1, "status": "completed", "amount": 100 },
    {
 "id": 2, "status": "pending", "amount": 200 },
    {
 "id": 3, "status": "completed", "amount": 150 }
  ]

}

需求:只获取已完成的订单。


    
    
    
  // 使用JMESPath提取
{{ $jmespath("orders[?status == 'completed'].amount", $json) }}
// 输出:[100, 150]

六、工作流元数据:workflow

这些方法帮助你访问当前工作流和执行的信息。

关键方法总览

方法说明示例
$execution.id当前执行的唯一ID{{ $execution.id }}
$execution.mode执行模式(test或production){{ $execution.mode }}
$workflow.id工作流ID{{ $workflow.id }}
$workflow.name工作流名称{{ $workflow.name }}
$workflow.active工作流是否激活{{ $workflow.active }}
$nodeVersion节点版本{{ $nodeVersion }}
$itemIndex当前item的索引(从0开始){{ $itemIndex }}

实战例子6:添加审计日志


    
    
    
  // 在返回结果中添加执行信息
return
 [
  {
    json
: {
      processedData
: $json,
      executionId
: $execution.id,
      executionMode
: $execution.mode,
      workflowName
: $workflow.name,
      processedAt
: $now.toISO(),
      itemIndex
: $itemIndex
    }
  }
];

七、便利方法:快速判断与转换

n8n提供了一些简化常见操作的便利函数。

常用便利方法

方法说明
$if(condition, valueIfTrue, valueIfFalse)条件判断(三元操作符的替代)
$ifEmpty(value, defaultValue)如果值为空则返回默认值
$evaluateExpression(expression)动态执行表达式字符串
$max(...)返回最大值
$min(...)返回最小值

实战例子7:优雅的条件处理


    
    
    
  // 方案1:使用$if方法
{{ $if($json.status === 'active', '激活', '未激活') }}

// 方案2:使用$ifEmpty处理空值

{{ $ifEmpty($json.nickname, $json.name) }}
// 如果nickname为空,则使用name


// 方案3:获取最大值

{{ $max($json.prices[0], $json.prices[1], $json.prices[2]) }}

八、完整实战案例:数据处理工作流

现在让我们构建一个完整的、可执行的工作流,综合应用所有学到的方法。

工作流需求

  1. 1. 从API获取用户订单数据
  2. 2. 过滤出已完成的订单
  3. 3. 计算每个订单的税后价格
  4. 4. 添加处理时间戳和审计信息
  5. 5. 生成最终报告

完整工作流JSON代码


    
    
    
  {
  "name"
: "数据处理综合案例",
  "nodes"
: [
    {

      "parameters"
: {},
      "name"
: "Start",
      "type"
: "n8n-nodes-base.start",
      "typeVersion"
: 1,
      "position"
: [250, 300]
    }
,
    {

      "parameters"
: {
        "method"
: "GET",
        "url"
: "https://jsonplaceholder.typicode.com/users/1/posts",
        "authentication"
: "none"
      }
,
      "name"
: "Fetch Orders",
      "type"
: "n8n-nodes-base.httpRequest",
      "typeVersion"
: 4.2,
      "position"
: [450, 300]
    }
,
    {

      "parameters"
: {
        "mode"
: "runOnceForAllItems",
        "jsCode"
: "// 使用Code节点处理所有订单数据\nconst allOrders = $input.all();\n\n// 过滤已完成的订单\nconst completedOrders = allOrders.filter(order => {\n  return order.json.completed === true;\n});\n\n// 为每个订单添加处理信息\nconst processedOrders = completedOrders.map((order, index) => {\n  const orderData = order.json;\n  const price = 100; // 示例价格\n  const taxRate = 0.13; // 13%税率\n  const taxAmount = price * taxRate;\n  const totalWithTax = price + taxAmount;\n  \n  return {\n    json: {\n      orderId: orderData.id,\n      title: orderData.title,\n      originalPrice: price,\n      taxAmount: taxAmount.toFixed(2),\n      totalWithTax: totalWithTax.toFixed(2),\n      processedAt: $now.toISO(),\n      executionMode: $execution.mode,\n      workflowName: $workflow.name,\n      itemIndex: index\n    }\n  };\n});\n\n// 返回处理后的数据\nreturn processedOrders.length > 0 ? processedOrders : [{\n  json: { message: '没有已完成的订单' }\n}];"
      }
,
      "name"
: "Process Data",
      "type"
: "n8n-nodes-base.code",
      "typeVersion"
: 2,
      "position"
: [650, 300]
    }
,
    {

      "parameters"
: {
        "jsCode"
: "// 汇总统计信息\nconst allItems = $input.all();\n\nconst summary = {\n  totalOrders: allItems.length,\n  totalRevenue: allItems.reduce((sum, item) => sum + parseFloat(item.json.totalWithTax || 0), 0).toFixed(2),\n  totalTax: allItems.reduce((sum, item) => sum + parseFloat(item.json.taxAmount || 0), 0).toFixed(2),\n  orders: allItems.map(item => item.json),\n  generatedAt: $now.toISO(),\n  workflowExecutionId: $execution.id\n};\n\nreturn [{\n  json: summary\n}];"
      }
,
      "name"
: "Generate Report",
      "type"
: "n8n-nodes-base.code",
      "typeVersion"
: 2,
      "position"
: [850, 300]
    }

  ]
,
  "connections"
: {
    "Start"
: {
      "main"
: [
        [
{ "node": "Fetch Orders", "type": "main", "index": 0 }]
      ]

    }
,
    "Fetch Orders"
: {
      "main"
: [
        [
{ "node": "Process Data", "type": "main", "index": 0 }]
      ]

    }
,
    "Process Data"
: {
      "main"
: [
        [
{ "node": "Generate Report", "type": "main", "index": 0 }]
      ]

    }

  }
,
  "settings"
: {}
}

工作流执行结果示例


    
    
    
  {
  "totalOrders"
: 5,
  "totalRevenue"
: "565.00",
  "totalTax"
: "65.00",
  "orders"
: [
    {

      "orderId"
: 1,
      "title"
: "订单1",
      "originalPrice"
: 100,
      "taxAmount"
: "13.00",
      "totalWithTax"
: "113.00",
      "processedAt"
: "2025-12-05T11:11:00.000Z",
      "executionMode"
: "production",
      "workflowName"
: "数据处理综合案例",
      "itemIndex"
: 0
    }

    // ... 更多订单项目

  ]
,
  "generatedAt"
: "2025-12-05T11:11:00.000Z",
  "workflowExecutionId"
: "abc123def456"
}

九、常见错误与调试技巧

错误1:访问不存在的字段


    
    
    
  // ❌ 错误:直接访问可能不存在的字段
{{ $json.user.profile.email }}  // 如果user或profile不存在会报错

// ✅ 正确:使用可选链

{{ $json.user?.profile?.email }}

// ✅ 正确:使用$ifEmpty

{{ $ifEmpty($json.user.profile.email, '邮箱未设置') }}

错误2:混淆$input的用法


    
    
    
  // ❌ 错误:$input不是函数
{{ $input(0) }}

// ✅ 正确:使用$input的方法

{{ $input.first().json }}
{{ $input.all().length }}

错误3:时间对象的错误使用


    
    
    
  // ❌ 错误:混淆JavaScript Date和Luxon DateTime
const
 date = new Date();  // JavaScript Date
{{ date.toISO() }}  // 报错,Date没有toISO方法

// ✅ 正确:使用n8n提供的$now

{{ $now.toISO() }}

调试技巧:使用console.log

在Code节点中,你可以使用console.log来调试:


    
    
    
  const data = $input.item.json;
console
.log("当前数据:", data);  // 这会输出到n8n的日志中

console
.log("执行模式:", $execution.mode);
console
.log("工作流名称:", $workflow.name);

return
 [{ json: data }];

十、性能优化建议

1. 选择正确的执行模式


    
    
    
  // ❌ 低效:逐条执行,多次处理
// 如果有1000条数据,这会执行1000次


// ✅ 高效:一次性处理所有数据

// Mode: Run Once for All Items

const
 allItems = $input.all();
const
 processed = allItems.map(item => {
  // 处理逻辑

  return
 item;
});

2. 避免不必要的API调用


    
    
    
  // ❌ 低效:在循环中调用API
for
 (const item of items) {
  const
 response = await this.helpers.httpRequest({
    method
: 'GET',
    url
: `https://api.example.com/user/${item.userId}`
  });
}

// ✅ 高效:一次性获取所有数据

const
 userIds = items.map(item => item.userId).join(',');
const
 response = await this.helpers.httpRequest({
  method
: 'GET',
  url
: `https://api.example.com/users?ids=${userIds}`
});

3. 早期过滤数据


    
    
    
  // 在Code节点中先过滤,减少后续处理
const
 filtered = $input.all()
  .filter(item => item.json.status === 'active')
  .map(item => item.json);

十一、最佳实践总结

实践说明
优先使用表达式简单操作用表达式,避免创建额外节点
Code节点用于复杂逻辑当表达式无法解决时才使用Code
添加数据验证总是检查数据是否存在和有效
使用有意义的节点名便于在表达式中引用和调试
记录审计信息添加时间戳和执行信息,便于追踪
合理使用批量处理大数据集时选择"一次运行所有项"模式
充分利用内置方法减少依赖,提高工作流性能

总结

n8n的内置方法与变量是构建高效自动化工作流的核心工具。通过本教程,你已经学到:

✅ 表达式和Code节点的区别与应用场景
✅ 如何访问和处理当前节点的输入数据
✅ 如何跨节点引用数据
✅ 强大的日期时间和JMESPath查询能力
✅ 工作流元数据的获取和使用
✅ 完整的实战工作流示例
✅ 常见错误和调试方法


引用链接

[1] 官方文档: https://docs.n8n.io/code/builtin/overview/
[2] n8n系列教程: https://www.undsky.com/blog/?category=n8n%E6%95%99%E7%A8%8B#