【问题标题】:Advanced JQ techniques高级 JQ 技术
【发布时间】:2021-11-11 03:51:14
【问题描述】:

我正在寻找一些帮助来增加我的 jq-foo,并且可以使用一些指导。我有一些使用 JQ 编写脚本的 etl 作业,我想看看是否有办法让运行在 CPU 利用率和/或速度方面更高效。

这是一个示例负载:

{
  "timestamp": 1636601959,
  "uniqueId": "Foo",
  "value": 10
},
{
  "timestamp": 1636601859,
  "uniqueId": "Bar",
  "value": 13
}

我想做一些类似(伪代码)的事情:

if [ (epoch 15 minutes ago) -le timestamp ]; then 
   name=uniqueId; value_total=value(total); uniqueId_count=(uniqueId(count_total))
fi

现在我在做类似(伪代码)的事情:

for jq[timestamps] in $(json); do
  if [ (epoch 15 minutes ago)  -le timestamp ]; then 
    name=uniqueId; value_total=(value_total + value); uniqueId_count=(uniqueId_count + 1). 
  fi
done

有没有一种方法可以在不使用 for 循环反复调用 jq 'select() ...' 来遍历每个对象的情况下简化这一点?

【问题讨论】:

  • 输出中的 .uniqueId_count 字段是否应该在整个输入中总计或逐项递增?
  • 该计数将是 uniqueId 在 json 文档中出现的总次数。所以我基本上需要得到最后 15 分钟内的 groupby(uniqueids) 总数。该值也将以类似的方式进行汇总。因此,如果 'foo' 出现在不同的时间戳但都在 15 分钟前,我需要总值(10 + n + n + 等)
  • 但在您的伪代码中,检查 timestamp -le (epoch 15 minutes ago) 会发现那些早于 15 分钟的项目,而不是“在过去 15 分钟内”
  • 啊,非常正确,我解释错了...应该在 15 分钟内...实际代码看起来像这样 if [ "${minutes_ago}" -le "${time}" ]; then 其中minutes_ago 是 15 分钟前的纪元,@987654329 @ 是 json 时间戳
  • 更新了我的答案以反映所有的变化(我希望如此)。

标签: json performance jq


【解决方案1】:

如果您去掉对象之间的逗号或将整个输入用数组括号括起来(为了获得正确的 JSON),那么您可以这样做(使用 {}{}{} 样式的 -s 选项,或删除它为[{],{},{}] 风格):

jq -s --argjson delta $((15*60)) --argjson addvalue 10 '

 (now - $delta) as $pivot
 | map(select(.timestamp >= $pivot))
 | group_by(.uniqueId)
 | map({
    name: first.uniqueId,
    value_total: map(.value) | (add + $addvalue),
    uniqueId_count: length
  })

' 

【讨论】:

  • 这太棒了,谢谢!我要试一试,看看我是否有运气......如果不用for 循环遍历每个对象,那就太好了
  • 我也编辑了我的 OP,value=10 实际上应该是 value_total=value(total)
猜你喜欢
  • 1970-01-01
  • 2011-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-25
  • 1970-01-01
相关资源
最近更新 更多