diff --git a/lib/mix/tasks/pleroma/search/meilisearch.ex b/lib/mix/tasks/pleroma/search/meilisearch.ex index 299fb5b14..07c0deea0 100644 --- a/lib/mix/tasks/pleroma/search/meilisearch.ex +++ b/lib/mix/tasks/pleroma/search/meilisearch.ex @@ -48,6 +48,16 @@ def run(["index"]) do ] ) + {:ok, _} = + meili_put( + "/indexes/objects/settings/filterable-attributes", + [ + "media", + "local", + "author" + ] + ) + IO.puts("Created indices. Starting to insert posts.") chunk_size = Pleroma.Config.get([Pleroma.Search.Meilisearch, :initial_indexing_chunk_size]) diff --git a/lib/pleroma/search/meilisearch.ex b/lib/pleroma/search/meilisearch.ex index 47265844b..e44c2d62a 100644 --- a/lib/pleroma/search/meilisearch.ex +++ b/lib/pleroma/search/meilisearch.ex @@ -3,8 +3,9 @@ defmodule Pleroma.Search.Meilisearch do require Pleroma.Constants alias Pleroma.Activity + alias Pleroma.User + alias Pleroma.Search.DatabaseSearch - import Pleroma.Search.DatabaseSearch import Ecto.Query @behaviour Pleroma.Search.SearchBackend @@ -86,10 +87,23 @@ def search(user, query, options \\ []) do only_media = Keyword.get(options, :only_media, false) only_local = Keyword.get(options, :local, false) + filter = + [] + |> maybe_restrict_local(user, only_local) + |> maybe_restrict_author(author) + |> maybe_restrict_blocked(user) + |> maybe_restrict_following(user, following) + |> maybe_restrict_media(only_media) + res = meili_post( "/indexes/objects/search", - %{q: query, offset: offset, limit: limit} + %{ + q: query, + offset: offset, + limit: limit, + filter: filter + } ) with {:ok, result} <- res do @@ -100,16 +114,11 @@ def search(user, query, options \\ []) do |> Activity.create_by_object_ap_id() |> Activity.with_preloaded_object() |> Activity.restrict_deactivated_users() - |> maybe_restrict_local(user, only_local) - |> maybe_restrict_author(author) - |> maybe_restrict_blocked(user) - |> maybe_restrict_following(user, following) - |> maybe_restrict_media(only_media) - |> maybe_fetch(user, query) + |> DatabaseSearch.maybe_fetch(user, query) |> order_by([object: obj], desc: obj.data["published"]) |> Pleroma.Repo.all() rescue - _ -> maybe_fetch([], user, query) + _ -> DatabaseSearch.maybe_fetch([], user, query) end end end @@ -141,6 +150,9 @@ def object_to_search_data(object) do %{ id: object.id, content: content, + media: length(data["attachment"]) > 0, + local: Pleroma.Object.local?(object), + author: data["actor"], ap: data["id"], published: published |> DateTime.to_unix() } @@ -174,4 +186,60 @@ def add_to_index(activity) do def remove_from_index(object) do meili_delete!("/indexes/objects/documents/#{object.id}") end + + defp maybe_restrict_local(f, user, only_local) do + limit = Pleroma.Config.get([:instance, :limit_to_local_content], :unauthenticated) + + case {only_local, limit, user} do + {true, _, _} -> restrict_local(f) + {_, :all, _} -> restrict_local(f) + {_, :unauthenticated, %User{}} -> f + {_, :unauthenticated, _} -> restrict_local(f) + {_, false, _} -> f + end + end + + defp restrict_local(f) do + ["local = true" | f] + end + + defp maybe_restrict_author(f, %User{ap_id: ap_id}) do + [~s"author = #{Jason.encode!(ap_id)}" | f] + end + + defp maybe_restrict_author(f, _), do: f + + defp maybe_restrict_blocked(f, user) do + blocked_users = User.blocked_users_ap_ids(user) + + case blocked_users do + [] -> f + _ -> restrict_blocked(f, blocked_users) + end + end + + defp restrict_blocked(f, blocked_users) do + [~s"author NOT IN #{Jason.encode!(blocked_users)}" | f] + end + + defp maybe_restrict_following(f, %User{} = user, true) do + following_users = User.following_ap_ids(user) + + case following_users do + [] -> f + _ -> restrict_following(f, following_users) + end + end + + defp maybe_restrict_following(f, _, _), do: f + + defp restrict_following(f, following_users) do + [~s"author IN #{Jason.encode!(following_users)}" | f] + end + + defp maybe_restrict_media(f, true) do + ["media = true" | f] + end + + defp maybe_restrict_media(f, _), do: f end