Skip to content

Commit c517520

Browse files
committed
matches_member support for custom props
1 parent 6195a38 commit c517520

File tree

4 files changed

+95
-1
lines changed

4 files changed

+95
-1
lines changed

lib/plausible/stats/base.ex

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,5 +551,14 @@ defmodule Plausible.Stats.Base do
551551
)
552552
end
553553

554-
defp filter_by_custom_prop(_, q), do: q
554+
defp filter_by_custom_prop({"event:props:" <> prop_name, {:matches_member, clauses}}, q) do
555+
regexes = Enum.map(clauses, &page_regex/1)
556+
557+
from(
558+
e in q,
559+
where:
560+
has_key(e, :meta, ^prop_name) and
561+
fragment("arrayExists(k -> match(?, k), ?)", get_by_key(e, :meta, ^prop_name), ^regexes)
562+
)
563+
end
555564
end

lib/plausible/stats/breakdown.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ defmodule Plausible.Stats.Breakdown do
194194
defp include_none_result?({:member, values}), do: Enum.member?(values, "(none)")
195195
defp include_none_result?({:not_member, values}), do: !Enum.member?(values, "(none)")
196196
defp include_none_result?({:matches, _}), do: false
197+
defp include_none_result?({:matches_member, _}), do: false
197198
defp include_none_result?(_), do: true
198199

199200
defp breakdown_sessions(_, _, _, [], _), do: []

test/plausible_web/controllers/api/external_stats_controller/timeseries_test.exs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,47 @@ defmodule PlausibleWeb.Api.ExternalStatsController.TimeseriesTest do
857857
assert first == %{"date" => "2021-01-01", "visitors" => 1}
858858
assert second == %{"date" => "2021-01-02", "visitors" => 0}
859859
end
860+
861+
test "filter by multiple custom event properties matching", %{conn: conn, site: site} do
862+
populate_stats(site, [
863+
build(:event,
864+
name: "Purchase",
865+
"meta.key": ["package", "browser"],
866+
"meta.value": ["business", "Chrome"],
867+
timestamp: ~N[2021-01-01 00:00:00]
868+
),
869+
build(:event,
870+
name: "Purchase",
871+
"meta.key": ["package", "browser"],
872+
"meta.value": ["business", "Firefox"],
873+
timestamp: ~N[2021-01-01 00:00:00]
874+
),
875+
build(:event,
876+
name: "Purchase",
877+
"meta.key": ["package", "browser"],
878+
"meta.value": ["personal", "Safari"],
879+
timestamp: ~N[2021-01-02 00:25:00]
880+
),
881+
build(:event,
882+
name: "Purchase",
883+
"meta.key": ["package"],
884+
"meta.value": ["business"],
885+
timestamp: ~N[2021-01-02 00:25:00]
886+
)
887+
])
888+
889+
conn =
890+
get(conn, "/api/v1/stats/timeseries", %{
891+
"site_id" => site.domain,
892+
"period" => "month",
893+
"date" => "2021-01-01",
894+
"filters" => "event:name==Purchase;event:props:browser==F*|S*"
895+
})
896+
897+
%{"results" => [first, second | _rest]} = json_response(conn, 200)
898+
assert first == %{"date" => "2021-01-01", "visitors" => 1}
899+
assert second == %{"date" => "2021-01-02", "visitors" => 1}
900+
end
860901
end
861902

862903
describe "metrics" do

test/plausible_web/controllers/api/stats_controller/pages_test.exs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,49 @@ defmodule PlausibleWeb.Api.StatsController.PagesTest do
112112
]
113113
end
114114

115+
test "returns top pages with :matches_member filter on custom pageview props", %{
116+
conn: conn,
117+
site: site
118+
} do
119+
populate_stats(site, [
120+
build(:pageview,
121+
pathname: "/1",
122+
"meta.key": ["prop"],
123+
"meta.value": ["bar"]
124+
),
125+
build(:pageview,
126+
pathname: "/2",
127+
"meta.key": ["prop"],
128+
"meta.value": ["foobar"]
129+
),
130+
build(:pageview,
131+
pathname: "/3",
132+
"meta.key": ["prop"],
133+
"meta.value": ["baar"]
134+
),
135+
build(:pageview,
136+
pathname: "/4",
137+
"meta.key": ["another"],
138+
"meta.value": ["bar"]
139+
),
140+
build(:pageview, pathname: "/5"),
141+
build(:pageview,
142+
pathname: "/6",
143+
"meta.key": ["prop"],
144+
"meta.value": ["near"]
145+
)
146+
])
147+
148+
filters = Jason.encode!(%{props: %{"prop" => "~bar|nea"}})
149+
conn = get(conn, "/api/stats/#{site.domain}/pages?period=day&filters=#{filters}")
150+
151+
assert json_response(conn, 200) == [
152+
%{"visitors" => 1, "name" => "/1"},
153+
%{"visitors" => 1, "name" => "/2"},
154+
%{"visitors" => 1, "name" => "/6"}
155+
]
156+
end
157+
115158
test "returns top pages with multiple filters on custom pageview props", %{
116159
conn: conn,
117160
site: site

0 commit comments

Comments
 (0)