jsonjq

jq query with multiple conditions not working


I'm trying to run a jq query with multiple conditions, where the fields in the condition are in different parts of the JSON. The second condition isn't narrowing things down, and I need help figuring out why. The JSON is below.

As a baseline, querying on one condition gives me the output I expect:

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

Narrowing this further, I see two entries for datastore in the JSON that match as expected:

$ NODE="host-inf-4"; cat pxctl-cd-list-short.json | jq -c '.[] | select (.SchedulerNodeName == '\"${NODE}\"').Configs[].ID'
"[datastore--21] adsadaiuhwiorgwipo/_00ca/hipeghwerwjks.vmdk"
"[datastore-21] ukisvljrosoowpg/_00mb/jjgowhohgiyfiaaawjo.vmdk"

I try adding another select statement for the second condition, which I expect to narrow down to one entry. But I get the same two entries:

$ NODE="host-inf-4"; cat pxctl-cd-list-short.json | jq -c '.[] | select (.SchedulerNodeName == '\"${NODE}\"') |  select ( .Configs[].PXType == "kvdb").Configs[].ID'
"[datastore--21] adsadaiuhwiorgwipo/_00ca/hipeghwerwjks.vmdk"
"[datastore-21] ukisvljrosoowpg/_00mb/jjgowhohgiyfiaaawjo.vmdk"

Same thing when I try to add the condition in the first select statement:

$ NODE="host-inf-4"; cat pxctl-cd-list-short.json | jq -c '.[] | select (.SchedulerNodeName == '\"${NODE}\"'  and .Configs[].PXType == "data" ).Configs[].ID'
"[datastore--21] adsadaiuhwiorgwipo/_00ca/hipeghwerwjks.vmdk"
"[datastore-21] ukisvljrosoowpg/_00mb/jjgowhohgiyfiaaawjo.vmdk"

Any thoughts on why adding the second condition isn't working?

The JSON is below.

{
 "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"
  }
 }
}

Solution

  • Loop over the .Configs first:

    jq --arg node "host-inf-4" '.[] | select (.SchedulerNodeName == $node).Configs[] | select(.PXType == "data").ID' /path/to/json
    
    # "[datastore-21] ukisvljrosoowpg/_00mb/jjgowhohgiyfiaaawjo.vmdk"
    

    And don't forget to use --arg instead of bash vars