meilisearch: respect meili’s result ranking
Meilisearch is already configured to return results sorted by a particular ranking configured in the meilisearch CLI task. Resorting the returned top results by date partially negates this and runs counter to what someone with tweaked settings expects. Issue and fix identified by AdamK2003 in https://akkoma.dev/AkkomaGang/akkoma/pulls/579 But instead of using a O(n^2) resorting, this commit directly retrieves results in the correct order from the database. Closes: https://akkoma.dev/AkkomaGang/akkoma/pulls/579
This commit is contained in:
parent
5d6cb6a459
commit
65aeaefa41
4 changed files with 45 additions and 3 deletions
|
@ -14,6 +14,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
## Added
|
||||
- Implement [FEP-67ff](https://codeberg.org/fediverse/fep/src/branch/main/fep/67ff/fep-67ff.md) (federation documentation)
|
||||
|
||||
## Fixed
|
||||
- Meilisearch: order of results returned from our REST API now actually matches how Meilisearch ranks results
|
||||
|
||||
## 2024.04
|
||||
|
||||
## Added
|
||||
|
|
|
@ -258,6 +258,27 @@ defmodule Pleroma.Activity do
|
|||
|
||||
def get_create_by_object_ap_id(_), do: nil
|
||||
|
||||
@doc """
|
||||
Accepts a list of `ap__id`.
|
||||
Returns a query yielding Create activities for the given objects,
|
||||
in the same order as they were specified in the input list.
|
||||
"""
|
||||
@spec get_presorted_create_by_object_ap_id([String.t()]) :: Ecto.Queryable.t()
|
||||
def get_presorted_create_by_object_ap_id(ap_ids) do
|
||||
from(
|
||||
a in Activity,
|
||||
join:
|
||||
ids in fragment(
|
||||
"SELECT * FROM UNNEST(?::text[]) WITH ORDINALITY AS ids(ap_id, ord)",
|
||||
^ap_ids
|
||||
),
|
||||
on:
|
||||
ids.ap_id == fragment("?->>'object'", a.data) and
|
||||
fragment("?->>'type'", a.data) == "Create",
|
||||
order_by: [asc: ids.ord]
|
||||
)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Accepts `ap_id` or list of `ap_id`.
|
||||
Returns a query.
|
||||
|
|
|
@ -5,7 +5,6 @@ defmodule Pleroma.Search.Meilisearch do
|
|||
alias Pleroma.Activity
|
||||
|
||||
import Pleroma.Search.DatabaseSearch
|
||||
import Ecto.Query
|
||||
|
||||
@behaviour Pleroma.Search.SearchBackend
|
||||
|
||||
|
@ -91,14 +90,13 @@ defmodule Pleroma.Search.Meilisearch do
|
|||
|
||||
try do
|
||||
hits
|
||||
|> Activity.create_by_object_ap_id()
|
||||
|> Activity.get_presorted_create_by_object_ap_id()
|
||||
|> Activity.with_preloaded_object()
|
||||
|> Activity.restrict_deactivated_users()
|
||||
|> maybe_restrict_local(user)
|
||||
|> maybe_restrict_author(author)
|
||||
|> maybe_restrict_blocked(user)
|
||||
|> maybe_fetch(user, query)
|
||||
|> order_by([object: obj], desc: obj.data["published"])
|
||||
|> Pleroma.Repo.all()
|
||||
rescue
|
||||
_ -> maybe_fetch([], user, query)
|
||||
|
|
|
@ -41,6 +41,26 @@ defmodule Pleroma.ActivityTest do
|
|||
assert activity == found_activity
|
||||
end
|
||||
|
||||
test "returns activities by object's AP id in requested presorted order" do
|
||||
a1 = insert(:note_activity)
|
||||
o1 = Object.normalize(a1, fetch: false).data["id"]
|
||||
|
||||
a2 = insert(:note_activity)
|
||||
o2 = Object.normalize(a2, fetch: false).data["id"]
|
||||
|
||||
a3 = insert(:note_activity)
|
||||
o3 = Object.normalize(a3, fetch: false).data["id"]
|
||||
|
||||
a4 = insert(:note_activity)
|
||||
o4 = Object.normalize(a4, fetch: false).data["id"]
|
||||
|
||||
found_activities =
|
||||
Activity.get_presorted_create_by_object_ap_id([o3, o2, o4, o1])
|
||||
|> Repo.all()
|
||||
|
||||
assert found_activities == [a3, a2, a4, a1]
|
||||
end
|
||||
|
||||
test "preloading a bookmark" do
|
||||
user = insert(:user)
|
||||
user2 = insert(:user)
|
||||
|
|
Loading…
Reference in a new issue