summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrinpatch <rinpatch@sdf.org>2020-09-24 18:27:55 +0000
committerrinpatch <rinpatch@sdf.org>2020-09-24 18:27:55 +0000
commitc788593f7ffbf87a1fd8032f7b481bfd12091d83 (patch)
tree2eb3a9fcf7ac110fd2b265934a806abda0af6424
parent151df9fc17ec01ab566c433571a263741ed1844f (diff)
parentdefca4a8b1e5baa03b308e77bf2386f135b2584d (diff)
Merge branch '2182-profile-search-improvements' into 'develop'
Resolve "Profile search by URL doesn't work correctly" Closes #2182 See merge request pleroma/pleroma!3030
-rw-r--r--CHANGELOG.md1
-rw-r--r--lib/pleroma/user/search.ex45
-rw-r--r--test/user_search_test.exs19
3 files changed, 59 insertions, 6 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5f5d01af3..1a1de99a7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Changed
+- Search: Users are now findable by their urls.
- Renamed `:await_up_timeout` in `:connections_pool` namespace to `:connect_timeout`, old name is deprecated.
- Renamed `:timeout` in `pools` namespace to `:recv_timeout`, old name is deprecated.
- The `discoverable` field in the `User` struct will now add a NOINDEX metatag to profile pages when false.
diff --git a/lib/pleroma/user/search.ex b/lib/pleroma/user/search.ex
index b8c648672..408295e0c 100644
--- a/lib/pleroma/user/search.ex
+++ b/lib/pleroma/user/search.ex
@@ -19,11 +19,21 @@ defmodule Pleroma.User.Search do
query_string = format_query(query_string)
- maybe_resolve(resolve, for_user, query_string)
+ # If this returns anything, it should bounce to the top
+ maybe_resolved = maybe_resolve(resolve, for_user, query_string)
+ maybe_ap_id_match = User.get_cached_by_ap_id(query_string)
+
+ top_user_ids =
+ case {maybe_resolved, maybe_ap_id_match} do
+ {{:ok, %User{} = user}, %User{} = other_user} -> [user.id, other_user.id]
+ {{:ok, %User{} = user}, _} -> [user.id]
+ {_, %User{} = user} -> [user.id]
+ _ -> []
+ end
results =
query_string
- |> search_query(for_user, following)
+ |> search_query(for_user, following, top_user_ids)
|> Pagination.fetch_paginated(%{"offset" => offset, "limit" => result_limit}, :offset)
results
@@ -47,7 +57,7 @@ defmodule Pleroma.User.Search do
end
end
- defp search_query(query_string, for_user, following) do
+ defp search_query(query_string, for_user, following, top_user_ids) do
for_user
|> base_query(following)
|> filter_blocked_user(for_user)
@@ -56,13 +66,20 @@ defmodule Pleroma.User.Search do
|> filter_internal_users()
|> filter_blocked_domains(for_user)
|> fts_search(query_string)
+ |> select_top_users(top_user_ids)
|> trigram_rank(query_string)
- |> boost_search_rank(for_user)
+ |> boost_search_rank(for_user, top_user_ids)
|> subquery()
|> order_by(desc: :search_rank)
|> maybe_restrict_local(for_user)
end
+ defp select_top_users(query, top_user_ids) do
+ from(u in query,
+ or_where: u.id in ^top_user_ids
+ )
+ end
+
defp fts_search(query, query_string) do
query_string = to_tsquery(query_string)
@@ -180,7 +197,7 @@ defmodule Pleroma.User.Search do
defp local_domain, do: Pleroma.Config.get([Pleroma.Web.Endpoint, :url, :host])
- defp boost_search_rank(query, %User{} = for_user) do
+ defp boost_search_rank(query, %User{} = for_user, top_user_ids) do
friends_ids = User.get_friends_ids(for_user)
followers_ids = User.get_followers_ids(for_user)
@@ -192,6 +209,7 @@ defmodule Pleroma.User.Search do
CASE WHEN (?) THEN (?) * 1.5
WHEN (?) THEN (?) * 1.3
WHEN (?) THEN (?) * 1.1
+ WHEN (?) THEN 9001
ELSE (?) END
""",
u.id in ^friends_ids and u.id in ^followers_ids,
@@ -200,11 +218,26 @@ defmodule Pleroma.User.Search do
u.search_rank,
u.id in ^followers_ids,
u.search_rank,
+ u.id in ^top_user_ids,
u.search_rank
)
}
)
end
- defp boost_search_rank(query, _for_user), do: query
+ defp boost_search_rank(query, _for_user, top_user_ids) do
+ from(u in subquery(query),
+ select_merge: %{
+ search_rank:
+ fragment(
+ """
+ CASE WHEN (?) THEN 9001
+ ELSE (?) END
+ """,
+ u.id in ^top_user_ids,
+ u.search_rank
+ )
+ }
+ )
+ end
end
diff --git a/test/user_search_test.exs b/test/user_search_test.exs
index 8529ce6db..68fda1c53 100644
--- a/test/user_search_test.exs
+++ b/test/user_search_test.exs
@@ -17,6 +17,25 @@ defmodule Pleroma.UserSearchTest do
describe "User.search" do
setup do: clear_config([:instance, :limit_to_local_content])
+ test "returns a resolved user as the first result" do
+ Pleroma.Config.put([:instance, :limit_to_local_content], false)
+ user = insert(:user, %{nickname: "no_relation", ap_id: "https://lain.com/users/lain"})
+ _user = insert(:user, %{nickname: "com_user"})
+
+ [first_user, _second_user] = User.search("https://lain.com/users/lain", resolve: true)
+
+ assert first_user.id == user.id
+ end
+
+ test "returns a user with matching ap_id as the first result" do
+ user = insert(:user, %{nickname: "no_relation", ap_id: "https://lain.com/users/lain"})
+ _user = insert(:user, %{nickname: "com_user"})
+
+ [first_user, _second_user] = User.search("https://lain.com/users/lain")
+
+ assert first_user.id == user.id
+ end
+
test "excludes invisible users from results" do
user = insert(:user, %{nickname: "john t1000"})
insert(:user, %{invisible: true, nickname: "john t800"})