Json对象选择

时间:2018-10-22 12:13:24

标签: json select jq

我有一个从Google Maps反向地理编码查询返回的大型JSON对象。 在此对象中,返回了许多可能的位置详细信息。

使用jq如何选择location_type为“ ROOFTOP”的第一个返回位置并获取formatted_address和place_id?

在下面的示例中,第一个条目的location_type为“ GEOMETRIC_CENTER” 第二个条目具有“ ROOFTOP” location_type。我想忽略带有“ 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 :(得分:0)

假设条目包含在数组中,则可以使用此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

答案 1 :(得分:0)

与其使用.[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"))