
本文详解如何使用 jolt 的 `shift` 操作正确复制原始数组、同时从数组首项中提取 `start` 和 `end` 字段构建独立的 `date` 数组,避免常见索引覆盖与路径匹配错误。
在使用 Jolt 进行 JSON 转换时,一个典型难点是:既要完整保留原始数组结构(如 "steps"),又要基于数组某一项(如首项)派生出全新字段结构(如 "date" 数组)。初学者常误用通配符 * 与具体索引 0 混合在同一层级,导致数组被意外覆盖或仅处理最后一项——这正是原问题中 "*": "steps[]" 未生效的根本原因。
? 问题根源分析
原 spec 中:
"steps": {
"*": "steps[]", // ✅ 正确:将 steps[*] 逐个追加到输出 steps 数组
"0": { // ❌ 冲突:同一层级下,"0" 是 "*” 的子集,但 Jolt 不支持“先通配再单独索引”的并行匹配
"#startDate": "date[0].name",
"start": "date[0].value",
"end": "date[1].value",
"#endDate": "date[1].name"
}
}Jolt 的 shift 操作对同一输入键(steps)的多个子路径规则不保证执行顺序,且当 * 已遍历全部元素后,"0" 规则可能被忽略或覆盖,最终仅 steps[0] 生效,造成数据丢失。
✅ 正确解法:利用动态引用 &1 与层级隔离
核心思路:将输入顶层键(steps)视为通用占位符,用 &1 动态捕获其原始键名,确保完整透传;再单独处理其第 0 项以构造 date。
推荐 spec 如下:
[
{
"operation": "shift",
"spec": {
"*": {
"@": "&1",
"0": {
"#startDate": "date[0].name",
"start": "date[0].value",
"#endDate": "date[1].name",
"end": "date[1].value"
}
}
}
}
]✨ 关键语法解析:
- "*":匹配输入根对象的所有键(此处即 "steps");
- "@": "&1":@ 表示原值(整个 steps 数组),&1 表示 上 1 层路径中的第一个捕获组(即 * 匹配到的键名 "steps"),等价于 "steps": "steps",实现无损复制;
- "0":在 steps 数组内部精准定位首元素(索引 0),从中提取字段并映射至 date 数组。
? 提示:&n 是 Jolt 的路径变量引用语法,&0 = 当前层级键名,&1 = 上一层键名,依此类推。此处 &1 确保了任意输入键名(如 "tasks" 替代 "steps")均可自动适配。
? 验证示例
输入 JSON:
{
"steps": [
{
"end": "2023-01-27T09:19:29.849298Z",
"id": "1",
"start": "2023-01-27T09:18:24.59325Z",
"name": "foo"
},
{
"end": "2023-01-28T09:19:29.849298Z",
"id": "2",
"start": "2023-01-28T09:18:24.59325Z",
"name": "bar"
}
]
}经上述 spec 处理后,精确输出:
{
"steps": [
{
"end": "2023-01-27T09:19:29.849298Z",
"id": "1",
"start": "2023-01-27T09:18:24.59325Z",
"name": "foo"
},
{
"end": "2023-01-28T09:19:29.849298Z",
"id": "2",
"start": "2023-01-28T09:18:24.59325Z",
"name": "bar"
}
],
"date": [
{
"name": "startDate",
"value": "2023-01-27T09:18:24.59325Z"
},
{
"name": "endDate",
"value": "2023-01-27T09:19:29.849298Z"
}
]
}⚠️ 注意事项与最佳实践
- *永远避免在同一 shift 规则中对同一输入路径混用 `和数字索引**(如"steps": { "*": ..., "0": ... }`),应提升层级统一匹配;
- 若需从任意指定索引(非仅 0)提取字段,可将 "0" 替换为 "1"、"2" 等,但需确保数组长度足够;
- date 数组长度固定为 2,若需动态扩展(如按步骤数生成多个日期对),需改用 modify-overwrite-beta + 循环逻辑,shift 本身不支持迭代;
- 建议在 Jolt Demo Site 中实时调试 spec,观察中间路径匹配过程。
掌握 &n 引用与层级化 shift 结构,是写出健壮、可维护 Jolt 转换逻辑的关键一步。










