【问题标题】:Search for array in jsonb field (address components from Google maps)在 jsonb 字段中搜索数组(来自 Google 地图的地址组件)
【发布时间】:2022-01-14 06:59:26
【问题描述】:

我有一个表events 有一个location_details jsonb 字段,有时是空的,有时是这样填充的:

{
  "icon": "https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/geocode-71.png",
  "name": "Boulevard Pershing",
  "geometry": {
    "location": {
      "lat": 48.8805276,
      "lng": 2.283755
    },
    "viewport": {
      "east": 2.285103980291502,
      "west": 2.282406019708498,
      "north": 48.8818765802915,
      "south": 48.8791786197085
    }
  },
  "html_attributions": [

  ],
  "address_components": [
    {
      "types": [
        "route"
      ],
      "long_name": "Boulevard Pershing",
      "short_name": "Boulevard Pershing"
    },
    {
      "types": [
        "locality",
        "political"
      ],
      "long_name": "Paris",
      "short_name": "Paris"
    },
    {
      "types": [
        "administrative_area_level_2",
        "political"
      ],
      "long_name": "Département de Paris",
      "short_name": "Département de Paris"
    },
    {
      "types": [
        "administrative_area_level_1",
        "political"
      ],
      "long_name": "Île-de-France",
      "short_name": "IDF"
    },
    {
      "types": [
        "country",
        "political"
      ],
      "long_name": "France",
      "short_name": "FR"
    },
    {
      "types": [
        "postal_code"
      ],
      "long_name": "75017",
      "short_name": "75017"
    }
  ]
}

我想让用户按位置搜索事件,而不是按精确位置(例如本例中的“路线”)。

对我如何做到这一点有任何想法吗?

【问题讨论】:

    标签: sql postgresql google-maps jsonb


    【解决方案1】:

    我解析了address_components,以便可以在 SQL 中轻松访问它们:

    {
      "icon": "https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/geocode-71.png",
      "name": "Boulevard Pershing",
      "geometry": {
        "location": {
          "lat": 48.8805276,
          "lng": 2.283755
        },
        "viewport": {
          "east": 2.285103980291502,
          "west": 2.282406019708498,
          "north": 48.8818765802915,
          "south": 48.8791786197085
        }
      },
      "html_attributions": [
    
      ],
      "address_components": [
        {
          "types": [
            "route"
          ],
          "long_name": "Boulevard Pershing",
          "short_name": "Boulevard Pershing"
        },
        {
          "types": [
            "locality",
            "political"
          ],
          "long_name": "Paris",
          "short_name": "Paris"
        },
        {
          "types": [
            "administrative_area_level_2",
            "political"
          ],
          "long_name": "Département de Paris",
          "short_name": "Département de Paris"
        },
        {
          "types": [
            "administrative_area_level_1",
            "political"
          ],
          "long_name": "Île-de-France",
          "short_name": "IDF"
        },
        {
          "types": [
            "country",
            "political"
          ],
          "long_name": "France",
          "short_name": "FR"
        },
        {
          "types": [
            "postal_code"
          ],
          "long_name": "75017",
          "short_name": "75017"
        }
      ],
      "address_components_parsed": {
        "route": {
          "short_name": "Boulevard Pershing",
          "long_name": "Boulevard Pershing"
        },
        "locality": {
          "short_name": "Paris",
          "long_name": "Paris"
        },
        "political": {
          "short_name": "FR",
          "long_name": "France"
        },
        "administrative_area_level_2": {
          "short_name": "Département de Paris",
          "long_name": "Département de Paris"
        },
        "administrative_area_level_1": {
          "short_name": "IDF",
          "long_name": "Île-de-France"
        },
        "country": {
          "short_name": "FR",
          "long_name": "France"
        },
        "postal_code": {
          "short_name": "75017",
          "long_name": "75017"
        }
      }
    }
    

    相关的红宝石代码:

      def location_details=(value)
        return if value.blank?
        value =
          value.is_a?(String) ? JSON.parse(value.presence || "{}") : (value || {})
        value["address_components_parsed"] =
          address_components_for(value["address_components"])
        super(value)
      rescue JSON::ParserError
        errors.add(:location_details, I18n.t("events.errors.is_not_valid_json"))
        super(value)
      end
    
      def address_components
        (location_details || {}).fetch("address_components_parsed", {})
      end
    
      def address_components_for(address_components)
        (location_details || {})
          .fetch("address_components", {})
          .each_with_object({}) do |el, acc|
            el["types"].each do |type|
              acc[type] ||= {}
              acc[type]["short_name"] = el["short_name"]
              acc[type]["long_name"] = el["long_name"]
            end
          end
      end
    

    【讨论】:

      猜你喜欢
      • 2020-05-03
      • 2015-09-24
      • 1970-01-01
      • 1970-01-01
      • 2016-08-05
      • 2015-08-15
      • 1970-01-01
      • 2016-11-08
      • 2011-08-18
      相关资源
      最近更新 更多