Skip to content

Commit

Permalink
support location filters when fetching location suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
RobertJoonas committed May 27, 2024
1 parent 650739b commit 0292e67
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 68 deletions.
133 changes: 76 additions & 57 deletions lib/plausible/stats/imported/imported.ex
Original file line number Diff line number Diff line change
Expand Up @@ -87,38 +87,41 @@ defmodule Plausible.Stats.Imported do
)
end

def merge_imported_country_suggestions(native_q, _site, %Plausible.Stats.Query{filters: [_ | _]}) do
native_q
end

def merge_imported_country_suggestions(native_q, _site, %Plausible.Stats.Query{
include_imported: false
}) do
native_q
end

def merge_imported_country_suggestions(native_q, site, query) do
native_q =
native_q
|> exclude(:order_by)
|> exclude(:select)
|> select([e], %{country_code: e.country_code, count: fragment("count(*)")})
supports_filter_set? =
Enum.all?(query.filters, fn filter ->
[_, filtered_prop | _] = filter
@property_to_table_mappings[filtered_prop] == "imported_locations"
end)

imported_q =
from i in Imported.Base.query_imported("imported_locations", site, query),
group_by: i.country,
select_merge: %{country_code: i.country, count: fragment("sum(?)", i.pageviews)}
if supports_filter_set? do
native_q =
native_q
|> exclude(:order_by)
|> exclude(:select)
|> select([e], %{country_code: e.country_code, count: fragment("count(*)")})

from(s in subquery(native_q),
full_join: i in subquery(imported_q),
on: s.country_code == i.country_code,
select: fragment("if(not empty(?), ?, ?)", s.country_code, s.country_code, i.country_code),
order_by: [desc: fragment("? + ?", s.count, i.count)]
)
end
imported_q =
from i in Imported.Base.query_imported("imported_locations", site, query),
group_by: i.country,
select_merge: %{country_code: i.country, count: fragment("sum(?)", i.pageviews)}

def merge_imported_region_suggestions(native_q, _site, %Plausible.Stats.Query{filters: [_ | _]}) do
native_q
from(s in subquery(native_q),
full_join: i in subquery(imported_q),
on: s.country_code == i.country_code,
select:
fragment("if(not empty(?), ?, ?)", s.country_code, s.country_code, i.country_code),
order_by: [desc: fragment("? + ?", s.count, i.count)]
)
else
native_q
end
end

def merge_imported_region_suggestions(native_q, _site, %Plausible.Stats.Query{
Expand All @@ -128,28 +131,34 @@ defmodule Plausible.Stats.Imported do
end

def merge_imported_region_suggestions(native_q, site, query) do
native_q =
native_q
|> exclude(:order_by)
|> exclude(:select)
|> select([e], %{region_code: e.subdivision1_code, count: fragment("count(*)")})
supports_filter_set? =
Enum.all?(query.filters, fn filter ->
[_, filtered_prop | _] = filter
@property_to_table_mappings[filtered_prop] == "imported_locations"
end)

imported_q =
from i in Imported.Base.query_imported("imported_locations", site, query),
where: i.region != "",
group_by: i.region,
select_merge: %{region_code: i.region, count: fragment("sum(?)", i.pageviews)}
if supports_filter_set? do
native_q =
native_q
|> exclude(:order_by)
|> exclude(:select)
|> select([e], %{region_code: e.subdivision1_code, count: fragment("count(*)")})

from(s in subquery(native_q),
full_join: i in subquery(imported_q),
on: s.region_code == i.region_code,
select: fragment("if(not empty(?), ?, ?)", s.region_code, s.region_code, i.region_code),
order_by: [desc: fragment("? + ?", s.count, i.count)]
)
end
imported_q =
from i in Imported.Base.query_imported("imported_locations", site, query),
where: i.region != "",
group_by: i.region,
select_merge: %{region_code: i.region, count: fragment("sum(?)", i.pageviews)}

def merge_imported_city_suggestions(native_q, _site, %Plausible.Stats.Query{filters: [_ | _]}) do
native_q
from(s in subquery(native_q),
full_join: i in subquery(imported_q),
on: s.region_code == i.region_code,
select: fragment("if(not empty(?), ?, ?)", s.region_code, s.region_code, i.region_code),
order_by: [desc: fragment("? + ?", s.count, i.count)]
)
else
native_q
end
end

def merge_imported_city_suggestions(native_q, _site, %Plausible.Stats.Query{
Expand All @@ -159,24 +168,34 @@ defmodule Plausible.Stats.Imported do
end

def merge_imported_city_suggestions(native_q, site, query) do
native_q =
native_q
|> exclude(:order_by)
|> exclude(:select)
|> select([e], %{city_id: e.city_geoname_id, count: fragment("count(*)")})
supports_filter_set? =
Enum.all?(query.filters, fn filter ->
[_, filtered_prop | _] = filter
@property_to_table_mappings[filtered_prop] == "imported_locations"
end)

imported_q =
from i in Imported.Base.query_imported("imported_locations", site, query),
where: i.city != 0,
group_by: i.city,
select_merge: %{city_id: i.city, count: fragment("sum(?)", i.pageviews)}
if supports_filter_set? do
native_q =
native_q
|> exclude(:order_by)
|> exclude(:select)
|> select([e], %{city_id: e.city_geoname_id, count: fragment("count(*)")})

from(s in subquery(native_q),
full_join: i in subquery(imported_q),
on: s.city_id == i.city_id,
select: fragment("if(? > 0, ?, ?)", s.city_id, s.city_id, i.city_id),
order_by: [desc: fragment("? + ?", s.count, i.count)]
)
imported_q =
from i in Imported.Base.query_imported("imported_locations", site, query),
where: i.city != 0,
group_by: i.city,
select_merge: %{city_id: i.city, count: fragment("sum(?)", i.pageviews)}

from(s in subquery(native_q),
full_join: i in subquery(imported_q),
on: s.city_id == i.city_id,
select: fragment("if(? > 0, ?, ?)", s.city_id, s.city_id, i.city_id),
order_by: [desc: fragment("? + ?", s.count, i.count)]
)
else
native_q
end
end

def merge_imported_filter_suggestions(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -663,11 +663,12 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
]
end

test "ignores imported data in country suggestions when filters applied", %{
conn: conn,
site: site,
site_import: site_import
} do
test "ignores imported data in country suggestions when a different property is filtered by",
%{
conn: conn,
site: site,
site_import: site_import
} do
populate_stats(site, site_import.id, [
build(:pageview, country_code: "EE", referrer_source: "Bing"),
build(:imported_locations, country: "GB")
Expand All @@ -684,6 +685,26 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
assert json_response(conn, 200) == [%{"value" => "EE", "label" => "Estonia"}]
end

test "queries imported countries when filtering by country", %{
conn: conn,
site: site,
site_import: site_import
} do
populate_stats(site, site_import.id, [
build(:imported_locations, date: ~D[2019-01-01], country: "EE")
])

filters = Jason.encode!(%{country: "EE"})

conn =
get(
conn,
"/api/stats/#{site.domain}/suggestions/country?period=month&date=2019-01-01&filters=#{filters}&q=&with_imported=true"
)

assert json_response(conn, 200) == [%{"value" => "EE", "label" => "Estonia"}]
end

test "ignores imported country data when not requested", %{
conn: conn,
site: site,
Expand Down Expand Up @@ -728,11 +749,12 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
end
end

test "ignores imported data in region suggestions when filters applied", %{
conn: conn,
site: site,
site_import: site_import
} do
test "ignores imported data in region suggestions when a different property is filtered by",
%{
conn: conn,
site: site,
site_import: site_import
} do
populate_stats(site, site_import.id, [
build(:pageview,
country_code: "EE",
Expand All @@ -753,6 +775,26 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
assert json_response(conn, 200) == [%{"value" => "EE-39", "label" => "Hiiumaa"}]
end

test "queries imported regions when filtering by region", %{
conn: conn,
site: site,
site_import: site_import
} do
populate_stats(site, site_import.id, [
build(:imported_locations, date: ~D[2019-01-01], region: "EE-39")
])

filters = Jason.encode!(%{region: "EE-39"})

conn =
get(
conn,
"/api/stats/#{site.domain}/suggestions/region?period=month&date=2019-01-01&filters=#{filters}&q=&with_imported=true"
)

assert json_response(conn, 200) == [%{"value" => "EE-39", "label" => "Hiiumaa"}]
end

test "ignores imported region data when not requested", %{
conn: conn,
site: site,
Expand Down Expand Up @@ -809,7 +851,7 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
end
end

test "ignores imported data in city suggestions when filters applied", %{
test "ignores imported data in city suggestions when a different property is filtered by", %{
conn: conn,
site: site,
site_import: site_import
Expand All @@ -835,6 +877,26 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
assert json_response(conn, 200) == [%{"value" => "591632", "label" => "Kärdla"}]
end

test "queries imported cities when filtering by city", %{
conn: conn,
site: site,
site_import: site_import
} do
populate_stats(site, site_import.id, [
build(:imported_locations, date: ~D[2019-01-01], city: 591_632)
])

filters = Jason.encode!(%{city: "591632"})

conn =
get(
conn,
"/api/stats/#{site.domain}/suggestions/city?period=month&date=2019-01-01&filters=#{filters}&q=&with_imported=true"
)

assert json_response(conn, 200) == [%{"value" => "591632", "label" => "Kärdla"}]
end

test "ignores imported city data when not requested", %{
conn: conn,
site: site,
Expand Down

0 comments on commit 0292e67

Please sign in to comment.