This commit is contained in:
Uku Taht 2023-04-18 10:31:39 +01:00 committed by Adam Rutkowski
parent bf9d6173a8
commit 6b3154b59e
3 changed files with 39 additions and 31 deletions

View File

@ -46,29 +46,20 @@ defmodule Plausible.Funnels do
Repo.one(q)
end
def evaluate(_query, funnel_id, site_id) do
funnel =
Repo.get_by(Funnel,
id: funnel_id,
site_id: site_id
)
# XXX: make inner join
|> Repo.preload(steps: :goal)
def evaluate(query, funnel_id, site_id) do
funnel = get(site_id, funnel_id)
q_events =
from e in "events_v2",
from(e in "events_v2",
select: %{
session_id: e.session_id,
step:
fragment(
"windowFunnel(?)(timestamp, pathname = '/product/car', name = 'Add to cart', pathname = '/view/checkout', name = 'Purchase')",
@funnel_window_duration
)
session_id: e.session_id
},
where: e.site_id == ^funnel.site_id,
group_by: e.session_id,
having: fragment("step > 0"),
order_by: [desc: fragment("step")]
)
|> select_funnel(query)
query =
from f in subquery(q_events),
@ -78,7 +69,6 @@ defmodule Plausible.Funnels do
funnel_result =
ClickhouseRepo.all(query)
|> Enum.into(%{})
|> IO.inspect(label: :query)
steps = update_step_defaults(funnel, funnel_result)
@ -88,25 +78,35 @@ defmodule Plausible.Funnels do
}
end
defp select_funnel(db_query, _stats_query) do
from(
q in db_query,
select_merge: %{
step:
fragment(
"windowFunnel(?)(timestamp, ?, ?, ?, ?)",
@funnel_window_duration
)
}
)
end
defp funnel_step_conditions() do
end
defp update_step_defaults(funnel, funnel_result) do
max_step = Enum.max_by(funnel.steps, & &1.step_order).step_order
funnel.steps
|> Enum.sort_by(& &1.step_order)
|> Enum.map(fn step ->
label =
Plausible.Goal.display_name(step.goal)
|> IO.inspect(label: :label)
label = Plausible.Goal.display_name(step.goal)
visitors_total =
Enum.reduce(step.step_order..max_step, 0, fn step_order, acc ->
visitors =
Map.get(funnel_result, step_order, 0)
|> IO.inspect(label: "visitors_#{step_order}")
visitors = Map.get(funnel_result, step_order, 0)
acc + visitors
end)
|> IO.inspect(label: :visitors_total)
%{
visitors: visitors_total,

View File

@ -4,9 +4,10 @@ defmodule PlausibleWeb.Api.FunnelsController do
alias Plausible.Funnels
@snippet """
import Plausible.Factory
Plausible.Repo.delete_all(Plausible.Goal)
Plausible.Repo.delete_all(Plausible.Funnel)
site = Plausible.Sites.get_by_domain("dummy.site")
site = Plausible.Sites.get_by_domain("dummy.site")
g1 = insert(:goal, site: site, page_path: "/product/car")
g2 = insert(:goal, site: site, event_name: "Add to cart")
@ -58,6 +59,7 @@ defmodule PlausibleWeb.Api.FunnelsController do
def show(conn, %{"id" => funnel_id}) do
site_id = conn.assigns.site.id
{funnel_id, ""} = Integer.parse(funnel_id)
funnel = Funnels.evaluate(:nop, funnel_id, site_id)
json(conn, funnel)

View File

@ -44,9 +44,9 @@ defmodule Plausible.GoalsTest do
nil
)
assert got =
Funnels.get(site, funnel.id)
|> IO.inspect(label: :got)
funnel = Funnels.get(site, funnel.id)
assert funnel.name == "Lorem ipsum"
assert [%{step_order: 1}, %{step_order: 2}, %{step_order: 3}] = funnel.steps
end
test "a funnel can be made of max n(TBD) goals" do
@ -72,14 +72,20 @@ defmodule Plausible.GoalsTest do
populate_stats(site, [
build(:pageview, pathname: "/go/to/blog/foo", user_id: 123),
build(:event, name: "Signup", user_id: 123),
build(:pageview, pathname: "/checkout", user_id: 123)
build(:pageview, pathname: "/checkout", user_id: 123),
build(:pageview, pathname: "/go/to/blog/bar", user_id: 666),
build(:event, name: "Signup", user_id: 666)
])
query = Plausible.Stats.Query.from(site, %{"period" => "all"})
funnel_data = Funnels.evaluate(query, funnel)
funnel_data = Funnels.evaluate(query, funnel.id, site.id)
assert %{
steps: [%{step: 3, visitors: 1}]
steps: [
%{label: "Visit /go/to/blog/**", visitors: 2},
%{label: "Signup", visitors: 2},
%{label: "Visit /checkout", visitors: 1}
]
} = funnel_data
end
end