JQ解析嵌套数组

时间:2018-07-25 09:49:13

标签: arrays json scope nested jq

我在从JSON获取数据时遇到问题:

{
  "operations": [
    {
      "operationName": "GetValue",
      "batch_size": "2",
      "orders": [
        {
          "clientId": "7836",
          "validation_time": {
            "place": "136",
            "execute": "5379"
          }
        },
        {
          "clientId": "7837",
          "validation_time": {
            "place": "145",
            "execute": "5401"
          }
        }
      ]
    },
    {
      "operationName": "GetValue",
      "batch_size": "3",
      "orders": [
        {
          "clientId": "7838",
          "validation_time": {
            "place": "122",
            "execute": "5201"
          }
        },
        {
          "clientId": "7839",
          "validation_time": {
            "place": "122",
            "execute": "5201"
          }
        },
        {
          "clientId": "7840",
          "validation_time": {
            "place": "122",
            "execute": "5201"
          }
        }
      ]
    }
  ]
}

因此,我想获取每个订单的信息,包括clientId作为键,每个订单的place_validation_time和execute_validation_time。我尝试了以下方法:

.operations[] | select(.operationName=="GetValue") | {key: .orders[].clientId, place_validation_time: .orders[].validation_time.place, execute_validation_time: .orders[].validation_time.execute, batch_size: .batch_size}

但是对我来说却有一个意想不到的结果,它结合了所有clientId以及validation_time.place和validation_time.execute的所有变体,因此我得到的不是每个订单1个对象,而是4个对象(对于batch_size = 2),例如 预期:

{
  "key": "7836",
  "place_validation_time": "136",
  "execute_validation_time": "5379",
  "batch_size": "2"
}

实际上我有:

{
  "key": "7836",
  "place_validation_time": "136",
  "execute_validation_time": "5379",
  "batch_size": "2"
}
{
  "key": "7836",
  "place_validation_time": "136",
  "execute_validation_time": "5401",
  "batch_size": "2"
}
{
  "key": "7836",
  "place_validation_time": "145",
  "execute_validation_time": "5379",
  "batch_size": "2"
}
{
  "key": "7836",
  "place_validation_time": "145",
  "execute_validation_time": "5401",
  "batch_size": "2"
}

有人知道如何避免它并因此每1个订单获得1个对象吗?

1 个答案:

答案 0 :(得分:2)

笛卡尔乘积行为是在对象构造表达式内的多个位置包含.orders[]的结果。改为吊起它。假设您要选择.batch_size等于“ 2”的对象,可以这样写:

.operations[]
| select(.operationName=="GetValue")
| .batch_size as $batch_size
| select($batch_size == "2")
| .orders[]
| {key: .clientId,
   place_validation_time: .validation_time.place,
   execute_validation_time: .validation_time.execute,
   batch_size: $batch_size}

附录

如果您在.batch_size级别还有其他感兴趣的项目,则可能需要使用这样的过滤器:

.operations[]
| select(.operationName=="GetValue")
| . as $it
| select($it.batch_size == "2")
| .orders[]
| {key: .clientId,
   place_validation_time: .validation_time.place,
   execute_validation_time: .validation_time.execute,
   batch_size: $it.batch_size}