Выбор из сложных вложенных данных JSON в JQ

У меня есть данные JSON, как это:

{
  "profiles": {
    "auto_scaler": [
      {
        "auto_scaler_group_name": "myasg0",
        "auto_scaler_group_options": {
          ":availability_zones": ["1a", "1b", "1c"],
          ":max_size": 1,
          ":min_size": 1,
          ":subnets": ["a", "b", "c"],
          ":tags": [
            {":key": "Name", ":value": "app0" },
            {":key": "env", ":value": "dev" },
            {":key": "role", ":value": "app" },
            {":key": "domain", ":value": "example.com" },
            {":key": "fonzi_app", ":value": "true"},
            {":key": "vpc", ":value": "nonprod"}
          ]
        },
        "dns_name": "fonz1"
      },
      {
        "auto_scaler_group_name": "myasg1",
        "auto_scaler_group_options": {
          ":availability_zones": ["1a", "1b", "1c"],
          ":max_size": 1,
          ":min_size": 1,
          ":subnets": ["a", "b", "c"],
          ":tags": [
            {":key": "Name", ":value": "app1" },
            {":key": "env", ":value": "dev" },
            {":key": "role", ":value": "app" },
            {":key": "domain", ":value": "example.com" },
            {":key": "bozo_app", ":value": "true"},
            {":key": "vpc", ":value": "nonprod"}
          ]
        },
        "dns_name": "bozo1"
      }
    ]
  }
}

Я хочу написать JQ-запрос, чтобы сначала выбрать элемент Hash в массиве в .profiles.auto_scaler чей массив хэшей в .auto_scaler_group_options.tags содержит хэши, содержащие ":key"ключ, значение которого содержит "fonzi"а":value"ключ, значение которого точно true а затем вернуть значение ключа dns_name,

В этом примере запрос просто вернет "fonz1",

Кто-нибудь знает, как это сделать, если это возможно, используя jq?

2 ответа

Решение

Короче да.

В длинных:

.profiles.auto_scaler[]
| .dns_name as $name
| .auto_scaler_group_options
| select( any(.[":tags"][];
             (.[":key"] | index("fonzi")) and (.[":value"] == "true")) )
| $name

Результат вышеупомянутого:

"fonz1"

Хитрость заключается в том, чтобы извлечь кандидата.dns_name, прежде чем углубиться в ваш "сложный вложенный JSON".

Альтернатива

Если ваш JQ не имеет anyвы могли бы (в данном конкретном случае) обойтись без него, заменив select Выражение выше с:

 select( .[":tags"][]
         | (.[":key"] | index("fonzi")) and (.[":value"] == "true") )

Имейте в виду, однако, что семантика двух выражений немного отличается. (Домашнее задание: в чем разница?)

Если ваш JQ не имеет any и если вы хотите семантику any, тогда вы можете легко свернуть свой собственный, или просто обновить:-)

Вы можете искать JSON числом или способами,

  1. проверяя свойство существует или нет
  2. используя синтаксис [property],
  3. 'свойство' в синтаксисе объекта

для вашего случая вот небольшой пример, далее вы можете посмотреть на массив и посмотреть

содержащий ключ "key", значение которого содержит EEE, и ключ "value", значение которого точно равно FFF

for(var k=0; k < p['AAA']['BBB'].length;k++){  
   console.log(p['AAA']['BBB'][k]) 
}

где p - объект JSON.

надеюсь, это поможет

Другие вопросы по тегам