Removed unused trigram index on `users`. Fixed `users_fts_index` usage.
authorIvan Tashkinov <ivantashkinov@gmail.com>
Wed, 8 Jul 2020 19:50:15 +0000 (22:50 +0300)
committerIvan Tashkinov <ivantashkinov@gmail.com>
Wed, 8 Jul 2020 19:50:15 +0000 (22:50 +0300)
lib/pleroma/user/search.ex
priv/repo/migrations/20200708193702_drop_user_trigram_index.exs [new file with mode: 0644]
test/user_search_test.exs

index 7ff1c7e24c912207577971299542f97ffdc0c757..d4fd310690e33f0c7d691f02e90aeb5ebac79ffd 100644 (file)
@@ -69,11 +69,15 @@ defmodule Pleroma.User.Search 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 @@ defmodule Pleroma.User.Search 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,
diff --git a/priv/repo/migrations/20200708193702_drop_user_trigram_index.exs b/priv/repo/migrations/20200708193702_drop_user_trigram_index.exs
new file mode 100644 (file)
index 0000000..94efe32
--- /dev/null
@@ -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
index 758822072dcb4e27d4fb966ae0600c04edacfe9e..559ba59668a057e10c75aec384c2ffeb34fe2d8d 100644 (file)
@@ -72,15 +72,11 @@ defmodule Pleroma.UserSearchTest 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