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

jq多条件查询失效求助:跨层级字段筛选无法缩小结果范围

问题描述

尝试用jq执行跨层级多条件查询,单条件筛选SchedulerNodeName能得到预期结果,但添加Configs.PXType的筛选条件后,无法缩小结果范围,所有Configs下的ID仍被返回。

单条件查询(正常工作)

筛选指定SchedulerNodeName的节点:

$ NODE="host-inf-4"; cat pxctl-cd-list-short.json | jq -c '.[] | select (.SchedulerNodeName == '"${NODE}"')'

返回包含该节点所有Configs的JSON结构,符合预期。

提取该节点下所有Configs的ID:

$ NODE="host-inf-4"; cat pxctl-cd-list-short.json | jq -c '.[] | select (.SchedulerNodeName == '"${NODE}"').Configs[].ID'

返回两个ID:

"[datastore--21] adsadaiuhwiorgwipo/_00ca/hipeghwerwjks.vmdk"
"[datastore-21] ukisvljrosoowpg/_00mb/jjgowhohgiyfiaaawjo.vmdk"

多条件查询失效情况

尝试添加PXType筛选条件(比如筛选kvdb或data),以下两种写法均无法缩小结果范围,仍返回全部两个ID:

$ NODE="host-inf-4"; cat pxctl-cd-list-short.json | jq -c '.[] | select (.SchedulerNodeName == '"${NODE}"') |  select ( .Configs[].PXType == "kvdb").Configs[].ID'
$ NODE="host-inf-4"; cat pxctl-cd-list-short.json | jq -c '.[] | select (.SchedulerNodeName == '"${NODE}"'  and .Configs[].PXType == "data" ).Configs[].ID'

对应的JSON结构:

{
 "1dfasdavsdfsvhoho028": {
  "Configs": {
   "[datastore-21] adsadaiuhwiorgwipo/_00ca/hipeghwerwjks.vmdk": {
    "Type": "zeroedthick",
    "Size": 32,
    "ID": "[datastore--21] adsadaiuhwiorgwipo/_00ca/hipeghwerwjks.vmdk",
    "PoolID": "",
    "Path": "/dev/sdc",
    "Iops": 0,
    "Vpus": 0,
    "PXType": "kvdb",
    "State": "Pending Add",
    "labels": {
     "datastore": "vsanDatastore"
    },
    "AttachOptions": {
     "ext": ".vmdk"
    },
    "Provisioner": "",
    "EncryptionKeyInfo": ""
   },
   "[datastore-21] ukisvljrosoowpg/_00mb/jjgowhohgiyfiaaawjo.vmdk": {
    "Type": "lazyzeroedthick",
    "Size": 150,
    "ID": "[datastore-21] ukisvljrosoowpg/_00mb/jjgowhohgiyfiaaawjo.vmdk",
    "PoolID": "a471iidfisaj8i8124asdadsoif8ie82",
    "Path": "/dev/sdb",
    "Iops": 0,
    "Vpus": 0,
    "PXType": "data",
    "State": "In Use",
    "labels": {
     "datastore": "vsanDatastore"
    },
    "AttachOptions": {
     "ext": ".vmdk"
    },
    "Provisioner": "",
    "EncryptionKeyInfo": ""
   }
  },
  "NodeID": "16a-8243r20-8fihqwc8-adew-2343ase",
  "ReservedInstanceID": "",
  "SchedulerNodeName": "host-inf-4",
  "NodeIndex": 12,
  "CreateTimestamp": "2024-11-22T00:27:38.432162311Z",
  "InstanceID": "42sdada08ihjpb3fe-6b-4873-0ya7-be80079acasca",
  "Zone": "default",
  "State": "In Use",
  "labels": {
   "px/metadata-node": "true"
  }
 }, 
 "asdada-42764533fff2": {
  "Configs": null,
  "NodeID": "1",
  "ReservedInstanceID": "",
  "SchedulerNodeName": "host-wkr-19",
  "NodeIndex": 19,
  "CreateTimestamp": "0001-01-01T00:00:00Z",
  "InstanceID": "asda0098q921",
  "Zone": "default",
  "State": "In Use",
  "labels": {
   "px/metadata-node": "false"
  }
 }
}
原因分析

写法错误在于将对象迭代(.Configs[])放在了select内部,导致:

  1. 当执行.Configs[].PXType == "kvdb"时,jq会遍历节点下所有Configs对象,只要其中一个满足条件,整个select就返回true,保留整个节点。
  2. 后续提取.Configs[].ID时,自然会返回该节点下所有Configs的ID,而非筛选后的结果。

简单说:你是先筛选节点(只要节点内存在符合PXType的Configs就保留),再提取该节点所有Configs的ID,而非直接筛选Configs对象。

解决方案

正确逻辑是:先筛选出目标节点,再遍历该节点的Configs对象,对每个Configs单独做筛选,最后提取符合条件的ID。

写法1:分步筛选

$ NODE="host-inf-4"; cat pxctl-cd-list-short.json | jq -c '.[] | select(.SchedulerNodeName == '"${NODE}"') | .Configs[] | select(.PXType == "kvdb") | .ID'

逻辑拆解:

  • .[]:遍历顶层所有节点
  • select(.SchedulerNodeName == ...):筛选出目标节点
  • .Configs[]:遍历该节点下所有Configs对象
  • select(.PXType == ...):筛选出符合PXType的Configs
  • .ID:提取该Configs的ID

写法2:用to_entries处理Configs

如果需要先在节点层面过滤Configs,再提取ID,可将Configs的键值对转为数组处理:

$ NODE="host-inf-4"; cat pxctl-cd-list-short.json | jq -c '.[] | select(.SchedulerNodeName == '"${NODE}"') | .Configs | to_entries[] | select(.value.PXType == "data") | .value.ID'

测试结果

执行第一种写法筛选kvdb时,返回:

"[datastore--21] adsadaiuhwiorgwipo/_00ca/hipeghwerwjks.vmdk"

筛选data时,返回:

"[datastore-21] ukisvljrosoowpg/_00mb/jjgowhohgiyfiaaawjo.vmdk"

符合预期。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 18:25:54