Выбор объекта Json - PullRequest
       12

Выбор объекта Json

0 голосов
/ 22 октября 2018

У меня есть большой объект JSON, возвращенный из обратного поиска геокодирования в Картах Google.в этом объекте возвращается много возможных деталей местоположения.

Используя jq, как выбрать первое возвращенное местоположение с типом location_type "ROOFTOP" и получить formatted_address и place_id?

в приведенном ниже примерепервая запись имеет тип location_type "GEOMETRIC_CENTER", вторая запись имеет тип location ROOFTOP.Я хочу проигнорировать запись с "GEOMETRIC_CENTER" и вернуть только первую запись с location_type "ROOFTOP"

Большое спасибо, Майк

  [
   {
     "address_components": [
       {
        "long_name": "30",
        "short_name": "30",
        "types": [
          "street_number"
        ]
      },
      {
        "long_name": "Allée Jean de Lattre de Tassigny",
        "short_name": "Allée Jean de Lattre de Tassigny",
        "types": [
          "route"
        ]
      },
      {
        "long_name": "Montpellier",
        "short_name": "Montpellier",
        "types": [
          "locality",
          "political"
        ]
      },
      {
        "long_name": "Hérault",
        "short_name": "Hérault",
        "types": [
          "administrative_area_level_2",
          "political"
        ]
      },
      {
        "long_name": "Occitanie",
        "short_name": "Occitanie",
        "types": [
          "administrative_area_level_1",
          "political"
        ]
      },
      {
        "long_name": "France",
        "short_name": "FR",
        "types": [
          "country",
          "political"
        ]
      },
      {
        "long_name": "34000",
        "short_name": "34000",
        "types": [
          "postal_code"
        ]
      }
    ],
    "formatted_address": "30 Allée Jean de Lattre de Tassigny, 34000 Montpellier, France",
    "geometry": {
      "bounds": {
        "northeast": {
          "lat": 43.6097932,
          "lng": 3.8817559
        },
        "southwest": {
          "lat": 43.6094097,
          "lng": 3.881321299999999
        }
      },
      "location": {
        "lat": 43.6095516,
        "lng": 3.881559199999999
      },
      "location_type": "GEOMETRIC_CENTER",
      "viewport": {
        "northeast": {
          "lat": 43.6109504302915,
          "lng": 3.882887580291503
        },
        "southwest": {
          "lat": 43.6082524697085,
          "lng": 3.880189619708498
        }
      }
    },
    "place_id": "ChIJ13k0paCvthIRcTgwBrisc10",
    "types": [
      "premise"
    ]
   },
   {
    "address_components": [
      {
        "long_name": "8",
        "short_name": "8",
        "types": [
          "street_number"
        ]
      },
      {
        "long_name": "Rue Michelet",
        "short_name": "Rue Michelet",
        "types": [
          "route"
        ]
      },
      {
        "long_name": "Montpellier",
        "short_name": "Montpellier",
        "types": [
          "locality",
          "political"
        ]
      },
      {
        "long_name": "Hérault",
        "short_name": "Hérault",
        "types": [
          "administrative_area_level_2",
          "political"
        ]
      },
      {
        "long_name": "Occitanie",
        "short_name": "Occitanie",
        "types": [
          "administrative_area_level_1",
          "political"
        ]
      },
      {
        "long_name": "France",
        "short_name": "FR",
        "types": [
          "country",
          "political"
        ]
      },
      {
        "long_name": "34000",
        "short_name": "34000",
        "types": [
          "postal_code"
        ]
      }
    ],
    "formatted_address": "8 Rue Michelet, 34000 Montpellier, France",
    "geometry": {
      "location": {
        "lat": 43.60911189999999,
        "lng": 3.8814264
      },
      "location_type": "ROOFTOP",
      "viewport": {
        "northeast": {
          "lat": 43.61046088029149,
          "lng": 3.882775380291502
        },
        "southwest": {
          "lat": 43.60776291970849,
          "lng": 3.880077419708498
        }
      }
    },
    "place_id": "ChIJ2UaGt6CvthIRJoNW7vS2Ibs",
    "plus_code": {
      "compound_code": "JV5J+JH Montpellier, France",
      "global_code": "8FM5JV5J+JH"
    },
    "types": [
      "street_address"
    ]
   }
  ]

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Вместо использования .[0] для получения первого удовлетворительного объекта было бы более эффективно использовать first/1.Вот решение, использующее first/1 и ..:

$ jq 'first(..|objects|select(.geometry.location_type == "ROOFTOP"))
      | {formatted_address, place_id}' input.json
{
  "formatted_address": "8 Rue Michelet, 34000 Montpellier, France",
  "place_id": "ChIJ2UaGt6CvthIRJoNW7vS2Ibs"
}

Использование first таким образом избавляет от необходимости вычислять весь массив перед получением первого элемента.

В качестве альтернативы...

Получение первого объекта верхнего уровня без использования ..:

first(.[] | select(.geometry.location_type=="ROOFTOP"))
0 голосов
/ 22 октября 2018

Предполагая, что записи заключены в массив, вы можете использовать этот фильтр jq, который выдает все объекты, имеющие ROOFTOP как location:

jq '.[] | select(.geometry.location_type=="ROOFTOP")' file

Если вы хотите выбрать только первоеодин из всех объектов, используйте следующее:

jq 'map(select(.geometry.location_type=="ROOFTOP"))|.[0]' file

И вам нужны только некоторые значения, передайте ему другой фильтр, подобный этому:

jq 'map(select(.geometry.location_type=="ROOFTOP"))|.[0]|.place_id, .formatted_address' file
...