From ca9826e2990102ae38615881e3d7798aa34ae3df Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Mon, 3 Oct 2022 14:02:25 +0200 Subject: [PATCH] Improve related events Signed-off-by: Thomas Citharel --- lib/graphql/resolvers/event.ex | 5 +--- lib/mobilizon/events/events.ex | 52 ++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/lib/graphql/resolvers/event.ex b/lib/graphql/resolvers/event.ex index 1b7632c8d..40d8dd906 100644 --- a/lib/graphql/resolvers/event.ex +++ b/lib/graphql/resolvers/event.ex @@ -211,10 +211,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do # We get the organizer's next public event events = event - |> organizer_next_public_event() - # We find similar events with the same tags - |> similar_events_common_tags(event) - # TODO: We should use tag_relations to find more appropriate events + |> Events.related_events() # We've considered all recommended events, so we fetch the latest events |> add_latest_events() # We remove the same event from the results diff --git a/lib/mobilizon/events/events.ex b/lib/mobilizon/events/events.ex index 3890b1031..22a3ec484 100644 --- a/lib/mobilizon/events/events.ex +++ b/lib/mobilizon/events/events.ex @@ -1686,6 +1686,58 @@ defmodule Mobilizon.Events do |> Repo.all() end + @threshold_related_value 7 + + def related_events(%Event{ + id: event_id, + tags: tags, + physical_address: %Address{geom: geom}, + category: category, + language: language + }) do + event_tags_ids = Enum.map(tags, & &1.id) + + Event + |> join(:left, [e], et in "events_tags", on: e.id == et.event_id) + |> join(:left, [e], a in Address, on: e.physical_address_id == a.id) + |> where( + [e, et, a], + fragment( + "(? = ?)::int * 5 + (? = ALL(?))::int * 2 + (? = ?)::int + (? is null or ST_DWithin(?::geography, ?::geography, ?::float))::int * 2 > ?", + e.language, + ^language, + et.tag_id, + ^event_tags_ids, + e.category, + ^category, + a.geom, + ^geom, + a.geom, + 5000, + @threshold_related_value + ) + ) + # |> where([e], e.begins_on > ^DateTime.utc_now()) + |> where([e], e.id != ^event_id) + |> order_by( + [e, et, a], + fragment( + "(? = ?)::int * 5 + (? = ALL(?))::int * 2 + (? = ?)::int + (? is null or ST_DWithin(?::geography, ?::geography, ?::float))::int * 2 DESC", + e.language, + ^language, + et.tag_id, + ^event_tags_ids, + e.category, + ^category, + a.geom, + ^geom, + a.geom, + 5000 + ) + ) + |> Repo.all() + end + @spec list_participations_for_user_query(integer()) :: Ecto.Query.t() defp list_participations_for_user_query(user_id) do from(