【n8n教程】:用 JMESPath 轻松查询和转换 JSON 数据

在日常工作中,我们经常需要处理 JSON 数据。无论是从 API 获取数据还是处理工作流中的中间结果,快速准确地提取和转换 JSON 数据都是必不可少的技能。

本教程将教你如何使用 JMESPath——一种功能强大的 JSON 查询语言——在 n8n 中轻松实现这一点。JMESPath 不仅能让你查询数据,还能帮你过滤、转换和聚合数据,而且代码简洁明了。

关键优势:相比复杂的 JavaScript 代码,JMESPath 语法更直观、更易学、更容易维护。


什么是 JMESPath?

JMESPath 是一种为 JSON 设计的查询语言。它让你能够:

为什么在 n8n 中使用 JMESPath?

在 n8n 中,jmespath() 方法是一个原生的、高效的工具,可以在代码节点中使用,避免了繁琐的 JavaScript 循环和条件判断。


快速入门:基础语法

1. 基本的 jmespath() 方法

在 n8n 的代码节点中,你可以这样使用:


    
    
    
  $jmespath(对象, "查询表达式")

例子


    
    
    
  // 从对象中提取特定字段
const
 data = { name: "张三", age: 28, city: "北京" };
$jmespath(data, "name")  // 结果: "张三"

2. 访问嵌套属性


    
    
    
  // 数据示例
const
 user = {
  id
: 1,
  profile
: {
    name
: "李四",
    contact
: {
      email
: "li@example.com"
    }
  }
};

// 使用点号访问嵌套字段

$jmespath(user, "profile.contact.email")  // 结果: "li@example.com"

3. 数组操作(投影)

这是 JMESPath 最强大的特性之一!

a) 列表投影 - 从数组提取所有对象的某个字段


    
    
    
  const people = [
  { firstName: "王", lastName: "五" },
  { firstName: "赵", lastName: "六" },
  { firstName: "孙", lastName: "七" }
];

// 提取所有人的名字

$jmespath(people, "[].firstName")
// 结果: ["王", "赵", "孙"]

b) 多选列表 - 从每个对象中提取多个字段


    
    
    
  const employees = [
  { id: 101, name: "张三", salary: 8000 },
  { id: 102, name: "李四", salary: 9000 },
  { id: 103, name: "王五", salary: 8500 }
];

// 提取 id 和 name,创建新的对象数组

$jmespath(employees, "[].{id: id, name: name}")
// 结果: [

//   { id: 101, name: "张三" },

//   { id: 102, name: "李四" },

//   { id: 103, name: "王五" }

// ]

c) 过滤投影 - 只选择满足条件的元素


    
    
    
  const products = [
  { id: 1, name: "笔记本", price: 5000, inStock: true },
  { id: 2, name: "鼠标", price: 80, inStock: false },
  { id: 3, name: "键盘", price: 200, inStock: true }
];

// 只获取有货的产品名称

$jmespath(products, "[?inStock == `true`].name")
// 结果: ["笔记本", "键盘"]


// 获取价格大于 100 的产品

$jmespath(products, "[?price > `100`].name")
// 结果: ["笔记本", "键盘"]

提示:在 JMESPath 中,布尔值和数字需要用反引号包裹(如 `true``100`)。


常见任务详解

任务 1:从 API 响应中提取特定数据

场景:你收到一个复杂的 API 响应,只需要其中的用户邮箱列表。

原始数据


    
    
    
  {
  "status"
: "success",
  "data"
: {
    "users"
: [
      {
 "id": 1, "email": "user1@example.com", "active": true },
      {
 "id": 2, "email": "user2@example.com", "active": false },
      {
 "id": 3, "email": "user3@example.com", "active": true }
    ]

  }

}

JMESPath 查询


    
    
    
  $jmespath(data, "data.users[].email")
// 结果: ["user1@example.com", "user2@example.com", "user3@example.com"]

任务 2:条件过滤 + 数据变换

场景:你需要找出所有活跃用户,并为他们创建一个新的格式。


    
    
    
  $jmespath(data, "data.users[?active == `true`].{userId: id, userEmail: email}")
// 结果:

// [

//   { userId: 1, userEmail: "user1@example.com" },

//   { userId: 3, userEmail: "user3@example.com" }

// ]

任务 3:使用切片提取数组的一部分


    
    
    
  const names = ["张三", "李四", "王五", "赵六", "孙七"];

// 获取前 3 个元素

$jmespath(names, "[0:3]")
// 结果: ["张三", "李四", "王五"]


// 获取最后 2 个元素

$jmespath(names, "[-2:]")
// 结果: ["赵六", "孙七"]

在 n8n 中的实际应用

在表达式中使用 JMESPath

除了代码节点,你还可以在 Set 节点 或其他支持表达式的节点中使用 JMESPath:


    
    
    
  // 在 Set 节点的表达式中
{{ $jmespath($json, "data.users[?active == `true`][].email") }}

在代码节点中处理多条数据

当代码节点设置为 "Run Once for Each Item" 时:


    
    
    
  // 处理单个数据项
const
 result = $jmespath($input.item.json, "user.profile.name");
return
 { json: { result } };

当代码节点设置为 "Run Once for All Items" 时:


    
    
    
  // 处理所有数据项
const
 allItems = $input.all();
const
 emails = $jmespath(allItems, "[].json.email");
return
 { json: { emails } };

完整工作流示例

现在让我们创建一个完整的、可直接导入的工作流,展示如何使用 JMESPath 处理真实数据。

工作流场景

从 Webhook 接收产品数据,使用 JMESPath 提取并转换数据,最后保存结果。

工作流 JSON(复制后可直接导入)


    
    
    
  {
  "name"
: "JMESPath 数据提取示例",
  "nodes"
: [
    {

      "parameters"
: {
        "httpMethod"
: "POST",
        "path"
: "jmespath-demo",
        "responseMode"
: "onReceived",
        "options"
: {}
      }
,
      "id"
: "webhook",
      "name"
: "Webhook",
      "type"
: "n8n-nodes-base.webhook",
      "typeVersion"
: 1,
      "position"
: [100, 100]
    }
,
    {

      "parameters"
: {
        "jsCode"
: "// 示例:从 webhook 数据中提取产品信息\nconst data = $input.item.json;\n\n// 使用 JMESPath 提取活跃产品\nconst activeProducts = $jmespath(\n  data, \n  \"products[?status == `active`].{id: id, name: name, price: price}\"\n);\n\n// 计算总价值\nconst totalValue = activeProducts.reduce((sum, p) => sum + p.price, 0);\n\nreturn {\n  json: {\n    productCount: activeProducts.length,\n    products: activeProducts,\n    totalValue: totalValue,\n    processedAt: new Date().toISOString()\n  }\n};"
      }
,
      "id"
: "code",
      "name"
: "Code",
      "type"
: "n8n-nodes-base.code",
      "typeVersion"
: 1,
      "position"
: [300, 100]
    }

  ]
,
  "connections"
: {
    "Webhook"
: {
      "main"
: [
        [

          {

            "node"
: "Code",
            "type"
: "main",
            "index"
: 0
          }

        ]

      ]

    }

  }

}

如何导入这个工作流

  1. 1. 在 n8n 中,点击 "导入工作流"
  2. 2. 将上方的 JSON 代码粘贴到输入框中
  3. 3. 点击 "导入" 按钮
  4. 4. 工作流将自动创建

测试工作流

向 Webhook 发送以下测试数据:


    
    
    
  {
  "products"
: [
    {

      "id"
: 1,
      "name"
: "笔记本电脑",
      "price"
: 5000,
      "status"
: "active"
    }
,
    {

      "id"
: 2,
      "name"
: "鼠标",
      "price"
: 80,
      "status"
: "inactive"
    }
,
    {

      "id"
: 3,
      "name"
: "键盘",
      "price"
: 200,
      "status"
: "active"
    }
,
    {

      "id"
: 4,
      "name"
: "显示器",
      "price"
: 1500,
      "status"
: "active"
    }

  ]

}

预期输出


    
    
    
  {
  "productCount"
: 3,
  "products"
: [
    {
 "id": 1, "name": "笔记本电脑", "price": 5000 },
    {
 "id": 3, "name": "键盘", "price": 200 },
    {
 "id": 4, "name": "显示器", "price": 1500 }
  ]
,
  "totalValue"
: 6700,
  "processedAt"
: "2025-12-05T11:30:00.000Z"
}

JMESPath 速查表

操作表达式示例
访问属性fieldname
嵌套属性parent.childuser.profile.email
数组索引array[0]users[0]
列表投影array[].fieldusers[].name
多选[].{field1: f1, field2: f2}[].{id: id, name: name}
过滤[?condition][?status == \active`]`
切片[start:end][0:3]
长度length(array)length(users)
排序sort(array)sort(names)
反转reverse(array)reverse(items)

常见错误排查

错误 1:布尔值和数字格式错误


    
    
    
  // ❌ 错误
[?status == true]   // 不能这样写

// ✅ 正确

[?status == `true`] // 使用反引号
[?price > `100`]    // 数字也要用反引号

错误 2:属性名中有特殊字符


    
    
    
  // 如果属性名中有空格或特殊字符,使用引号
$jmespath(data, '"product-name"')
$jmespath(data, '"user name"')

错误 3:忘记转义反引号


    
    
    
  // 在表达式中,如果需要使用反引号,确保正确转义
// 在 n8n 表达式中: {{ $jmespath($json, "field[?value == \`test\`]") }}

总结

通过本教程,你已经掌握了:

✅ JMESPath 的基础语法
✅ 如何在 n8n 中使用 $jmespath() 方法
✅ 数组投影、过滤和多选等高级操作
✅ 实际工作流中的应用技巧
✅ 常见问题的解决方案


引用链接

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