You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于JOLT构建复杂嵌套JSON对象的技术求助

求助:JOLT中为嵌套JSON数组的所有对象统一添加同一JobId值

我现在在尝试用JOLT构建一个复杂的嵌套JSON对象数组,但始终得不到想要的结构,卡在这里了。我之前看JOLT官网的递归迭代内容,但这个概念有点绕,没太搞明白。我的核心需求是:不管数组里有多少个对象(哪怕上千个),所有对象里的JobId必须是同一个毫秒值,所以我只想生成一次这个值,但就是没法把它放到所有需要的位置上。麻烦各位帮忙看看!

输入JSON

{ "type": "FeatureCollection", "totalFeatures": 2, "features": [ { "type": "Feature", "geometry": { "type": "Point", "coordinates": [ 13.429916995511855, 52.54516530881942 ] }, "properties": { "feature_type": "BLDG", "feature_geometry": "point", "discipline": "LOC", "activity": "AC", "be_number": 12313, "category": 47400, "condition": "RDY", "review_date": "2018-03-28T21:36:32.325Z", "role_type": "INSG", "symbol_code": "-" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [ 16.429916995511855, 91.54516530881942 ] }, "properties": { "feature_type": "Bridge", "feature_geometry": "point", "discipline": "LOC", "activity": "AC", "co_number": 12313, "category": 47400, "condition": "RDY", "review_date": "2018-03-28T21:36:32.325Z", "role_type": "KLDV", "symbol_code": "-" } } ] }

当前使用的JOLT规则

[{ "operation": "shift", "spec": { "type": "type", "features": { "*": { "geometry": { "coordinates": { "0": "FacilityComposite[&3].Facility.Ilat", "1": "FacilityComposite[&3].Facility.Ilon" } }, "properties": { "activity": "FacilityComposite[&2].Facility.Activity", "be_number": "FacilityComposite[&2].Facility.BeNumber", "category": "FacilityComposite[&2].Facility.Category", "condition": "FacilityComposite[&2].Facility.Condition", "role_type": ["FacilityComposite[&2].Facility.RoleType", "FacilityComposite[&2].FacForm.RoleType", "FacilityComposite[&2].FacTie[&2].RoleType"], "review_date": ["FacilityComposite[&2].Facility.ReviewDate", "FacilityComposite[&2].FacForm.ReviewDate", "FacilityComposite[&2].FacTie[&2].ReviewDate"] } } } } }, { "operation": "default", "spec": { "JobId": "${now():toNumber()}", "FacilityComposite[]": { "*": { "Facility": { "FacSk": "-1", "ClientId": "DISHNET", "ReviewDate": "${now()}" }, "FacForm": { "FacSk": "-1", "ClientId": "DISHNET" }, "FacTie": [{ "FacTieSk": "-1", "TieFromSk": "-1", "TieToSk": "-1", "ClientId": "DISHNET" }] } } } } ]

当前规则生成的输出

{ "type" : "FeatureCollection", "FacilityComposite" : [ { "Facility" : { "Ilat" : 13.429916995511855, "Ilon" : 52.54516530881942, "Activity" : "AC", "BeNumber" : 12313, "Category" : 47400, "Condition" : "RDY", "RoleType" : "INSG", "ReviewDate" : "2018-03-28T21:36:32.325Z", "ClientId" : "DISHNET", "FacSk" : "-1" }, "FacForm" : { "RoleType" : "INSG", "ReviewDate" : "2018-03-28T21:36:32.325Z", "FacSk" : "-1", "ClientId" : "DISHNET" }, "FacTie" : [ { "RoleType" : "INSG", "ReviewDate" : "2018-03-28T21:36:32.325Z" } ] }, { "Facility" : { "Ilat" : 16.429916995511856, "Ilon" : 91.54516530881942, "Activity" : "AC", "Category" : 47400, "Condition" : "RDY", "RoleType" : "KLDV", "ReviewDate" : "2018-03-28T21:36:32.325Z", "ClientId" : "DISHNET", "FacSk" : "-1" }, "FacForm" : { "RoleType" : "KLDV", "ReviewDate" : "2018-03-28T21:36:32.325Z", "FacSk" : "-1", "ClientId" : "DISHNET" }, "FacTie" : [ null, { "RoleType" : "KLDV", "ReviewDate" : "2018-03-28T21:36:32.325Z" } ] } ], "JobId" : "${now():toNumber()}" }

预期输出

{ "type" : "FeatureCollection", "FacilityComposite" : [ { "Facility" : { "JobId" : "${now():toNumber()}", "Ilat" : 13.429916995511855, "Ilon" : 52.54516530881942, "Activity" : "AC", "BeNumber" : 12313, "Category" : 47400, "Condition" : "RDY", "RoleType" : "INSG", "ReviewDate" : "2018-03-28T21:36:32.325Z", "ClientId" : "DISHNET", "FacSk" : "-1" }, "FacForm" : { "JobId" : "${now():toNumber()}", "RoleType" : "INSG", "ReviewDate" : "2018-03-28T21:36:32.325Z", "FacSk" : "-1", "ClientId" : "DISHNET" }, "FacTie" : [ { "FacTieSk": "-1", "TieFromSk": "-1", "TieToSk": "-1", "JobId" : "${now():toNumber()}", "ClientId": "DISHNET", "RoleType" : "INSG", "ReviewDate" : "2018-03-28T21:36:32.325Z" } ] }, { "Facility" : { "JobId" : "${now():toNumber()}", "Ilat" : 16.429916995511856, "Ilon" : 91.54516530881942, "Activity" : "AC", "Category" : 47400, "Condition" : "RDY", "RoleType" : "KLDV", "ReviewDate" : "2018-03-28T21:36:32.325Z", "ClientId" : "DISHNET", "FacSk" : "-1" }, "FacForm" : { "JobId" : "${now():toNumber()}", "RoleType" : "KLDV", "ReviewDate" : "2018-03-28T21:36:32.325Z", "FacSk" : "-1", "ClientId" : "DISHNET" }, "FacTie" : [ { "FacTieSk": "-1", "TieFromSk": "-1", "TieToSk": "-1", "JobId" : "${now():toNumber()}", "ClientId": "DISHNET", "RoleType" : "KLDV", "ReviewDate" : "2018-03-28T21:36:32.325Z" } ] } ] }

解决方案

你的核心问题是需要把顶层生成的同一个JobId值,传递到嵌套的每个对象里,同时还要修正当前规则里的一些小问题(比如FacTie数组的索引错误导致的null值)。这里给你调整后的JOLT规则:

[
  // 第一步:先在顶层生成唯一的JobId,确保整个转换过程中值固定
  {
    "operation": "modify-default-beta",
    "spec": {
      "JobId": "${now():toNumber()}"
    }
  },
  // 第二步:完成结构映射,同时将顶层JobId传递到所有需要的嵌套位置
  {
    "operation": "shift",
    "spec": {
      "type": "type",
      "JobId": "JobId", // 可选:保留顶层JobId,不需要的话可以删除这一行
      "features": {
        "*": {
          "geometry": {
            "coordinates": {
              "0": "FacilityComposite[&3].Facility.Ilat",
              "1": "FacilityComposite[&3].Facility.Ilon"
            }
          },
          "properties": {
            "activity": "FacilityComposite[&2].Facility.Activity",
            "be_number": "FacilityComposite[&2].Facility.BeNumber",
            "category": "FacilityComposite[&2].Facility.Category",
            "condition": "FacilityComposite[&2].Facility.Condition",
            "role_type": [
              "FacilityComposite[&2].Facility.RoleType",
              "FacilityComposite[&2].FacForm.RoleType",
              "FacilityComposite[&2].FacTie[0].RoleType" // 修正索引:每个FacTie只有一个元素,用[0]避免null
            ],
            "review_date": [
              "FacilityComposite[&2].Facility.ReviewDate",
              "FacilityComposite[&2].FacForm.ReviewDate",
              "FacilityComposite[&2].FacTie[0].ReviewDate" // 同样修正索引
            ]
          },
          // 引用顶层的JobId,传递到当前Feature对应的三个嵌套对象中
          "@(2,JobId)": [
            "FacilityComposite[&1].Facility.JobId",
            "FacilityComposite[&1].FacForm.JobId",
            "FacilityComposite[&1].FacTie[0].JobId"
          ]
        }
      }
    }
  },
  // 第三步:添加默认值,注意不再重复生成JobId
  {
    "operation": "default",
    "spec": {
      "FacilityComposite[]": {
        "*": {
          "Facility": {
            "FacSk": "-1",
            "ClientId": "DISHNET"
            // 移除了ReviewDate的默认设置,避免覆盖输入中的原始日期
          },
          "FacForm": {
            "FacSk": "-1",
            "ClientId": "DISHNET"
          },
          "FacTie": [
            {
              "FacTieSk": "-1",
              "TieFromSk": "-1",
              "TieToSk": "-1",
              "ClientId": "DISHNET"
            }
          ]
        }
      }
    }
  }
]

关键调整说明

  1. 固定JobId生成时机:用modify-default-beta提前在顶层生成一次JobId,确保整个转换过程中这个值是唯一且不变的,不会因为多次生成导致不一致。
  2. 传递JobId到嵌套对象:在shift操作中,通过@(2,JobId)引用顶层的JobId值,将其映射到Facility、FacForm、FacTie[0]三个需要的位置,保证所有对象使用同一个值。
  3. 修正FacTie数组索引:原来的FacTie[&2]会导致第二个Feature的FacTie数组出现null值,改成FacTie[0]后,每个Feature的FacTie数组只会有一个元素,结构更符合预期。
  4. 避免覆盖原始数据:移除了默认规则中对Facility.ReviewDate的设置,保留输入中的原始日期值,不会被当前时间覆盖。

这样调整后,就能得到你想要的结构,所有嵌套对象里的JobId都会是同一个毫秒值,同时也解决了之前的结构错误问题。


内容的提问来源于stack exchange,提问作者user1997772

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:09:08