Ensure fts is prefered over trigram and use union_all instead of union in user search...
authorrinpatch <rinpatch@sdf.org>
Fri, 22 Mar 2019 05:39:49 +0000 (08:39 +0300)
committerrinpatch <rinpatch@sdf.org>
Fri, 22 Mar 2019 05:39:49 +0000 (08:39 +0300)
lib/pleroma/user.ex
test/user_test.exs

index e16141edcc84eb2b1d79c6996e9cc74d13208387..f2ef0a838e87b9f9c8998146fe312734e14a9a7e 100644 (file)
@@ -50,6 +50,7 @@ defmodule Pleroma.User do
     field(:local, :boolean, default: true)
     field(:follower_address, :string)
     field(:search_rank, :float, virtual: true)
+    field(:search_type, :integer, virtual: true)
     field(:tags, {:array, :string}, default: [])
     field(:bookmarks, {:array, :string}, default: [])
     field(:last_refreshed_at, :naive_datetime_usec)
@@ -835,8 +836,8 @@ defmodule Pleroma.User do
   def search_query(query, for_user) do
     fts_subquery = fts_search_subquery(query)
     trigram_subquery = trigram_search_subquery(query)
-    union_query = from(s in trigram_subquery, union: ^fts_subquery)
-    distinct_query = from(s in subquery(union_query), distinct: s.id)
+    union_query = from(s in trigram_subquery, union_all: ^fts_subquery)
+    distinct_query = from(s in subquery(union_query), order_by: s.search_type, distinct: s.id)
 
     from(s in subquery(boost_search_rank_query(distinct_query, for_user)),
       order_by: [desc: s.search_rank],
@@ -884,6 +885,7 @@ defmodule Pleroma.User do
     from(
       u in query,
       select_merge: %{
+        search_type: ^0,
         search_rank:
           fragment(
             """
@@ -916,6 +918,8 @@ defmodule Pleroma.User do
     from(
       u in User,
       select_merge: %{
+        # ^1 gives 'Postgrex expected a binary, got 1' for some weird reason
+        search_type: fragment("?", 1),
         search_rank:
           fragment(
             "similarity(?, trim(? || ' ' || coalesce(?, '')))",
index 1f54f3e30dae5ccc9e4530e77df2150faaa79433..442599910bff55b2bbc27ad7c33ed26f985e3741 100644 (file)
@@ -879,7 +879,11 @@ defmodule Pleroma.UserTest do
       user = insert(:user, %{nickname: "john"})
 
       Enum.each(["john", "jo", "j"], fn query ->
-        assert user == User.search(query) |> List.first() |> Map.put(:search_rank, nil)
+        assert user ==
+                 User.search(query)
+                 |> List.first()
+                 |> Map.put(:search_rank, nil)
+                 |> Map.put(:search_type, nil)
       end)
     end
 
@@ -887,7 +891,11 @@ defmodule Pleroma.UserTest do
       user = insert(:user, %{name: "John Doe"})
 
       Enum.each(["John Doe", "JOHN", "doe", "j d", "j", "d"], fn query ->
-        assert user == User.search(query) |> List.first() |> Map.put(:search_rank, nil)
+        assert user ==
+                 User.search(query)
+                 |> List.first()
+                 |> Map.put(:search_rank, nil)
+                 |> Map.put(:search_type, nil)
       end)
     end
 
@@ -941,6 +949,7 @@ defmodule Pleroma.UserTest do
                User.search("lain@pleroma.soykaf.com")
                |> List.first()
                |> Map.put(:search_rank, nil)
+               |> Map.put(:search_type, nil)
     end
 
     test "does not yield false-positive matches" do
@@ -958,7 +967,7 @@ defmodule Pleroma.UserTest do
       user = User.get_by_ap_id("http://mastodon.example.org/users/admin")
 
       assert length(results) == 1
-      assert user == result |> Map.put(:search_rank, nil)
+      assert user == result |> Map.put(:search_rank, nil) |> Map.put(:search_type, nil)
     end
   end