@@ -452,6 +452,18 @@ defmodule Plausible.Stats.Filters.QueryParser do
452452 }
453453 end
454454
455+ @ doc """
456+ Finds unique segment IDs used in query filters.
457+
458+ ## Examples
459+ iex> get_segment_ids([[:not, [:is, "segment", [10, 20]]], [:contains, "visit:entry_page", ["blog"]]])
460+
461+ {:ok, [10, 20]}
462+
463+ iex> get_segment_ids([[:and, [[:is, "segment", Enum.to_list(1..6)], [:is, "segment", Enum.to_list(1..6)]]]])
464+
465+ {:error, "Invalid filters. You can only use up to 10 segment filters in a query."}
466+ """
455467 def get_segment_ids ( filters ) do
456468 max_segment_filters_count = 10
457469
@@ -500,13 +512,37 @@ defmodule Plausible.Stats.Filters.QueryParser do
500512 end
501513
502514 defp replace_segment_with_filter_tree ( [ _ , "segment" , clauses ] , preloaded_segments ) do
503- [ [ :or , Enum . map ( clauses , fn id -> [ :and , Map . get ( preloaded_segments , id ) ] end ) ] ]
515+ if length ( clauses ) === 1 do
516+ [ [ :and , Map . get ( preloaded_segments , Enum . at ( clauses , 0 ) ) ] ]
517+ else
518+ [ [ :or , Enum . map ( clauses , fn id -> [ :and , Map . get ( preloaded_segments , id ) ] end ) ] ]
519+ end
504520 end
505521
506- defp replace_segment_with_filter_tree ( _filter_tree , _preloaded_segments ) do
507- nil
522+ defp replace_segment_with_filter_tree ( filter , _preloaded_segments ) do
523+ [ filter ]
508524 end
509525
526+ @ doc """
527+ ## Examples
528+
529+ iex> resolve_segments([[:is, "visit:entry_page", ["/home"]]], %{})
530+ {:ok, [[:is, "visit:entry_page", ["/home"]]]}
531+
532+ iex> resolve_segments([[:is, "visit:entry_page", ["/home"]], [:is, "segment", [1]]], %{1 => [[:contains, "visit:entry_page", ["blog"]], [:is, "visit:country", ["PL"]]]})
533+ {:ok, [
534+ [:is, "visit:entry_page", ["/home"]],
535+ [:and, [[:contains, "visit:entry_page", ["blog"]], [:is, "visit:country", ["PL"]]]]
536+ ]}
537+
538+ iex> resolve_segments([[:is, "segment", [1, 2]]], %{1 => [[:contains, "event:goal", ["Singup"]], [:is, "visit:country", ["PL"]]], 2 => [[:contains, "event:goal", ["Sauna"]], [:is, "visit:country", ["EE"]]]})
539+ {:ok, [
540+ [:or, [
541+ [:and, [[:contains, "event:goal", ["Singup"]], [:is, "visit:country", ["PL"]]]],
542+ [:and, [[:contains, "event:goal", ["Sauna"]], [:is, "visit:country", ["EE"]]]]]
543+ ]
544+ ]}
545+ """
510546 def resolve_segments ( original_filters , preloaded_segments ) do
511547 if Map . keys ( preloaded_segments ) !== [ ] do
512548 { :ok ,
0 commit comments