Compare commits

...

2 Commits

Author SHA1 Message Date
itepechi f50c6ac957
Ignore meili_data on Docker builds 2024-05-03 06:46:54 +09:00
itepechi 1b6a18b473
Improve search results by implementing filtering on the Meilisearch side
You will need to rerun the `search.meilisearch index` task in order to
support this. If you do not, Akkoma will only be able to filter for
newer posts than this commit and will return an error for advanced
searches if you did not update the `filterable-attributes` attribute on
the `objects` index manually.
2024-05-03 06:46:48 +09:00
3 changed files with 88 additions and 9 deletions

View File

@ -24,6 +24,7 @@ static
uploads uploads
instance instance
docker-db docker-db
meili_data
capture.pcap capture.pcap
erl_crash.dump erl_crash.dump
coveralls.json coveralls.json

View File

@ -48,6 +48,16 @@ defmodule Mix.Tasks.Pleroma.Search.Meilisearch do
] ]
) )
{:ok, _} =
meili_put(
"/indexes/objects/settings/filterable-attributes",
[
"media",
"local",
"author"
]
)
IO.puts("Created indices. Starting to insert posts.") IO.puts("Created indices. Starting to insert posts.")
chunk_size = Pleroma.Config.get([Pleroma.Search.Meilisearch, :initial_indexing_chunk_size]) chunk_size = Pleroma.Config.get([Pleroma.Search.Meilisearch, :initial_indexing_chunk_size])

View File

@ -3,8 +3,9 @@ defmodule Pleroma.Search.Meilisearch do
require Pleroma.Constants require Pleroma.Constants
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.User
alias Pleroma.Search.DatabaseSearch
import Pleroma.Search.DatabaseSearch
import Ecto.Query import Ecto.Query
@behaviour Pleroma.Search.SearchBackend @behaviour Pleroma.Search.SearchBackend
@ -86,10 +87,23 @@ defmodule Pleroma.Search.Meilisearch do
only_media = Keyword.get(options, :only_media, false) only_media = Keyword.get(options, :only_media, false)
only_local = Keyword.get(options, :local, 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 = res =
meili_post( meili_post(
"/indexes/objects/search", "/indexes/objects/search",
%{q: query, offset: offset, limit: limit} %{
q: query,
offset: offset,
limit: limit,
filter: filter
}
) )
with {:ok, result} <- res do with {:ok, result} <- res do
@ -100,16 +114,11 @@ defmodule Pleroma.Search.Meilisearch do
|> Activity.create_by_object_ap_id() |> Activity.create_by_object_ap_id()
|> Activity.with_preloaded_object() |> Activity.with_preloaded_object()
|> Activity.restrict_deactivated_users() |> Activity.restrict_deactivated_users()
|> maybe_restrict_local(user, only_local) |> DatabaseSearch.maybe_fetch(user, query)
|> maybe_restrict_author(author)
|> maybe_restrict_blocked(user)
|> maybe_restrict_following(user, following)
|> maybe_restrict_media(only_media)
|> maybe_fetch(user, query)
|> order_by([object: obj], desc: obj.data["published"]) |> order_by([object: obj], desc: obj.data["published"])
|> Pleroma.Repo.all() |> Pleroma.Repo.all()
rescue rescue
_ -> maybe_fetch([], user, query) _ -> DatabaseSearch.maybe_fetch([], user, query)
end end
end end
end end
@ -141,6 +150,9 @@ defmodule Pleroma.Search.Meilisearch do
%{ %{
id: object.id, id: object.id,
content: content, content: content,
media: length(data["attachment"]) > 0,
local: Pleroma.Object.local?(object),
author: data["actor"],
ap: data["id"], ap: data["id"],
published: published |> DateTime.to_unix() published: published |> DateTime.to_unix()
} }
@ -174,4 +186,60 @@ defmodule Pleroma.Search.Meilisearch do
def remove_from_index(object) do def remove_from_index(object) do
meili_delete!("/indexes/objects/documents/#{object.id}") meili_delete!("/indexes/objects/documents/#{object.id}")
end 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 end