【问题标题】:JQ using an ETL, to create an inner array, in a JSON ArrayJQ 使用 ETL,在 JSON 数组中创建内部数组
【发布时间】:2019-08-20 12:32:41
【问题描述】:

我需要使用 ETL 更新内部数组;

我想在 JSON 树的数组元素中创建一个新属性

类似

    def insideETL(keyname; arrayname; cond; result):
      def etl:
        . as $parent
        | .[arrayname][]
        | { parent: $parent, child: .}
        | select(cond) | result;

      map ( . 
            +
            {(keyname): map(etl)}
          )
    ;

来自以前的question

几乎得到了所需的结果,但我确实需要在 Main JSON 数组的每个项目中创建多个数组;

要过滤的数据

[
 {
        "storeId": "s2",
        "storehouseInfo": {
            "id": "025453",
            "name": "00211 NW, OR",
            "maxPallets": 10
        },
        "workorder":{
            "id": "w2s2",
            "startDate": "2019-09-06T10:00:00.000Z",
            "vendorId":"v2"
        },
        "events": [    
            {
                "id": "e4",
                "storeId": "s2",
                "vendorId": "v1",
                "startDate": "2019-09-05T10:00:00.000Z",
                "endDate": "2019-09-14T00:00:00.000Z",
                "palletsUsed": 5
            },
            {
                "id": "e5",
                "storeId": "s2",
                "vendorId": "v2",
                "startDate": "2019-09-05T00:00:00.000Z",
                "endDate": "2019-09-14T00:00:00.000Z",
                "palletsUsed": 5
            },
            {
                "id": "e10",
                "storeId": "s2",
                "vendorId": "v1",
                "startDate": "2019-09-06T10:00:00.000Z",
                "endDate": "2019-09-14T00:00:00.000Z",
                "palletsUsed": 5
            },
            {
                "id": "e11",
                "storeId": "s2",
                "vendorId": "v2",
                "startDate": "2019-09-06T00:00:00.000Z",
                "endDate": "2019-09-14T00:00:00.000Z",
                "palletsUsed": 5
            },
            {
                "id": "e12",
                "storeId": "s2",
                "vendorId": "v2",
                "startDate": "2019-09-06T10:00:00.000Z",
                "endDate": "2019-09-14T00:00:00.000Z",
                "palletsUsed": 5
            }
        ]
    },
]

所需的调用

.| 
  insideETL("conflictsInPeriod";
    "events";
    ( (.parent.workorder.startDate | dateDaysAgo(12*7) ) < .child.endDate)
      and
      (.child.vendorId == .parent.workorder.vendorId);
   {
     event: .child.id,
     wo_sd: .parent.workorder.startDate[:10],
     workorder_id: .parent.workorder.id
   }
)

期望的输出

    [
        {
            // our newly added array 
            "conflictsInPeriod":[
                {
                    "event":"e5",
                    "workorder_sd":"2019-09-06",
                    "workorder_id":"w2s2"
                },
                {
                    "event_id":"e11",
                    "workorder_sd":"2019-09-06",
                    "workorder_id":"w2s2"
                },
                {
                    "event_id":"e12",
                    "workorder_sd":"2019-09-06",
                    "workorder_id":"w2s2"
                }
            ],
            // all the other previous information in the Item
            "storeId":"s2",
            "storehouseInfo":{
                "id":"025453",
                "name":"00211 NW, OR",
                "maxPallets":10
            },
            "workorder":{
                "id":"w2s2",
                "startDate":"2019-09-06T10:00:00.000Z",
                "vendorId":"v2"
            },
            "events":[
                // ...  All the events data
            ]
        }
    ]

希望清楚,如果需要任何澄清...请发表评论。

【问题讨论】:

  • @oguz-ismail 你说得对,帖子很大,我正在尝试提供 Input DataDesired Ouput result 来制作它更清楚。还从另一个答案中删除了一些代码,而是仅将其链接作为参考...

标签: json jq


【解决方案1】:

我认为与其将自己束手无策,不如建立在已经开发和测试过的可重用组件之上:

def etl(keyname; arrayname; cond; result):
  def etl:
    . as $parent
    | .[arrayname][]
    | { parent: $parent, child: .}
    | select(cond) | result;
 {(keyname): map(etl)}
 ;

这是一种方法:

def add(arrayname):
  etl(arrayname;
    "events";
    ( (.parent.workorder.startDate | dateDaysAgo(12*7) ) < .child.endDate)
      and
      (.child.vendorId == .parent.workorder.vendorId);
   {
     event: .child.id,
     wo_sd: .parent.workorder.startDate[:10],
     workorder_id: .parent.workorder.id
   }
  )
  ;

[add("conflictsInPeriod") + .[]]

使用etl,您拥有一个可重用的组件,它允许多种变化,同时保持简单。

【讨论】:

  • 您已经提供的 ETL 解决方案是 awesome™,并且已经有多个用例。但在这种特殊情况下,我需要在 Outer 数组的 每个元素 内创建 "conflictsInPeriod",过滤该范围内的数组。跨度>
  • 例如如果您使用相同的元素两次而不是:[{conflictResults:[], rest_of_data_1... }, {conflictResults:[] , rest_of_data_2} ],您将拥有:[{**Allthe**conflictResults:[] ]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-21
  • 2021-12-19
  • 1970-01-01
  • 2017-05-27
  • 2016-04-19
相关资源
最近更新 更多