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
instance
docker-db
meili_data
capture.pcap
erl_crash.dump
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.")
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
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 @@ defmodule Pleroma.Search.Meilisearch 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 @@ defmodule Pleroma.Search.Meilisearch 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 @@ defmodule Pleroma.Search.Meilisearch 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 @@ defmodule Pleroma.Search.Meilisearch 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