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.
This commit is contained in:
parent
5adae54d52
commit
1b6a18b473
2 changed files with 87 additions and 9 deletions
|
@ -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.")
|
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])
|
||||||
|
|
|
@ -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 @@ def search(user, query, options \\ []) 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 @@ def search(user, query, options \\ []) 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 @@ def object_to_search_data(object) 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 @@ def add_to_index(activity) 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
|
||||||
|
|
Loading…
Reference in a new issue