Removed unused trigram index on `users`. Fixed `users_fts_index` usage.

This commit is contained in:
Ivan Tashkinov 2020-07-08 22:50:15 +03:00
parent 704a383055
commit 123352ffa1
3 changed files with 33 additions and 13 deletions

View File

@ -69,11 +69,15 @@ defp fts_search(query, query_string) do
u in query,
where:
fragment(
# The fragment must _exactly_ match `users_fts_index`, otherwise the index won't work
"""
(to_tsvector('simple', ?) || to_tsvector('simple', ?)) @@ to_tsquery('simple', ?)
(
setweight(to_tsvector('simple', regexp_replace(?, '\\W', ' ', 'g')), 'A') ||
setweight(to_tsvector('simple', regexp_replace(coalesce(?, ''), '\\W', ' ', 'g')), 'B')
) @@ to_tsquery('simple', ?)
""",
u.name,
u.nickname,
u.name,
^query_string
)
)
@ -95,9 +99,11 @@ defp trigram_rank(query, query_string) do
select_merge: %{
search_rank:
fragment(
"similarity(?, ?) + \
similarity(?, regexp_replace(?, '@.+', '')) + \
similarity(?, trim(coalesce(?, '')))",
"""
similarity(?, ?) +
similarity(?, regexp_replace(?, '@.+', '')) +
similarity(?, trim(coalesce(?, '')))
""",
^query_string,
u.nickname,
^query_string,

View File

@ -0,0 +1,18 @@
defmodule Pleroma.Repo.Migrations.DropUserTrigramIndex do
@moduledoc "Drops unused trigram index on `users` (FTS index is being used instead)"
use Ecto.Migration
def up do
drop_if_exists(index(:users, [], name: :users_trigram_index))
end
def down do
create_if_not_exists(
index(:users, ["(trim(nickname || ' ' || coalesce(name, ''))) gist_trgm_ops"],
name: :users_trigram_index,
using: :gist
)
)
end
end

View File

@ -72,15 +72,11 @@ test "finds a user by full name or leading fragment(s) of its words" do
end)
end
test "is not [yet] capable of matching by non-leading fragments (e.g. by domain)" do
user1 = insert(:user, %{nickname: "iamthedude"})
insert(:user, %{nickname: "arandom@dude.com"})
test "matches by leading fragment of user domain" do
user = insert(:user, %{nickname: "arandom@dude.com"})
insert(:user, %{nickname: "iamthedude"})
assert [] == User.search("dude")
# Matching by leading fragment works, though
user1_id = user1.id
assert ^user1_id = User.search("iam") |> List.first() |> Map.get(:id)
assert [user.id] == User.search("dud") |> Enum.map(& &1.id)
end
test "ranks full nickname match higher than full name match" do