~ihabunek/triglav

0751e8cc252e0a88ee48cf147d945d1128125879 — Ivan Habunek 1 year, 2 months ago 142a1bb
Add some indexed columns to speed up queries
M lib/mix/tasks/triglav/import_osm.ex => lib/mix/tasks/triglav/import_osm.ex +11 -0
@@ 38,7 38,18 @@ defmodule Mix.Tasks.Triglav.ImportOsm do
      ])

      Repo.query("ALTER TABLE planet_osm_rels ADD COLUMN tags_hstore hstore")
      Repo.query("ALTER TABLE planet_osm_rels ADD COLUMN type text")
      Repo.query("ALTER TABLE planet_osm_rels ADD COLUMN ref text")
      Repo.query("ALTER TABLE planet_osm_rels ADD COLUMN is_zet boolean")

      Repo.query("UPDATE planet_osm_rels SET tags_hstore = tags::hstore")
      Repo.query("UPDATE planet_osm_rels SET type = tags_hstore->'type'")
      Repo.query("UPDATE planet_osm_rels SET ref = tags_hstore->'ref'")
      Repo.query("UPDATE planet_osm_rels SET is_zet = (lower(tags_hstore->'operator') in ('zet', 'zagrebački električni tramvaj')")

      Repo.query("CREATE INDEX idx_planet_osm_rels_is_zet ON planet_osm_rels(is_zet)")
      Repo.query("CREATE INDEX idx_planet_osm_rels_type ON planet_osm_rels(type)")
      Repo.query("CREATE INDEX idx_planet_osm_rels_ref ON planet_osm_rels(ref)")

      IO.puts("Saving state...")
      Triglav.DataImport.save_state(web_state)

M lib/triglav/schemas/osm/relation.ex => lib/triglav/schemas/osm/relation.ex +4 -1
@@ 13,7 13,10 @@ defmodule Triglav.Schemas.Osm.Relation do
    field :tags_array, {:array, :string}, source: :tags
    field :tags, :map, source: :tags_hstore

    field :type, :string, virtual: true
    # Added columns
    field :type, :string
    field :ref, :string
    field :is_zet, :boolean
  end

  def get_tag(relation, name) do

M lib/triglav/zet/osm.ex => lib/triglav/zet/osm.ex +2 -10
@@ 14,19 14,11 @@ defmodule Triglav.Zet.Osm do

  defp pt_relations() do
    from(r in Relation,
      # This is not great for performance, but with our amount of data should be fine
      where:
        fragment("? -> ? in (?, ?)", r.tags, "type", "route", "route_master") and
          (fragment("? -> ? ilike ?", r.tags, "operator", "ZET") or
             fragment("? -> ? ilike ?", r.tags, "operator", "Zagrebački električni tramvaj")),
      select: %{r | type: fragment("? -> ?", r.tags, "type")}
      where: r.type in ["route", "route_master"] and r.is_zet
    )
  end

  defp filter_by_ref(query, ref: ref) do
    where(query, [r], fragment("? -> ? = ?", r.tags, "ref", ^ref))
  end

  defp filter_by_ref(query, ref: ref), do: where(query, [r], r.ref == ^ref)
  defp filter_by_ref(query, _), do: query

  # Consider moving this to the database